使用 PHP PayPal REST API 退款?
Refund using PHP PayPal REST API?
我正在开发一个集成到 PayPal 的 REST API 中的 PHP 应用程序。我已正确处理事务并将事务 ID 保存到 MySQL 数据库中。我现在正尝试退款,但无法让它停止给出 "Incoming JSON request does not map to API request" 错误。有人对如何让它工作有任何建议吗?
我在代码中留下了我的一些尝试,并对它们的结果进行了评论。我对让这个工作的方向感到有点迷茫。任何帮助将不胜感激。
我一直在关注位于此处的文档:
https://developer.paypal.com/docs/integration/direct/payments/refund-payment/
我可能很难使该请求适应 PHP。
我找到了这段代码:
https://github.com/paypal/PayPal-PHP-SDK/blob/master/sample/payments/RefundCapture.php
但它是 'requiring' 一个文件树,对于一个简单的退款请求来说似乎有点过多。
<?php
require_once(dirname(__FILE__) . '/paypalSDK/autoload.php'); // require paypal files
require_once(dirname(__FILE__) . '/paypalSDK/paypal/rest-api-sdk-php/sample/common.php'); // require paypal files
// call required stuff
use PayPal\Api\Address;
use PayPal\Api\Amount;
use PayPal\Api\Details;
use PayPal\Api\ExecutePayment;
use PayPal\Api\FundingInstrument;
use PayPal\Api\Item;
use PayPal\Api\ItemList;
use PayPal\Api\Payer;
use PayPal\Api\Payment;
use PayPal\Api\PaymentCard;
use PayPal\Api\PaymentExecution;
use PayPal\Api\Transaction;
use PayPal\Api\Capture;
use PayPal\Api\Refund;
use PayPal\Api\RefundRequest;
use PayPal\Api\Sale;
$orderID = $_GET['order_id']; // order ID we wish to refund
// pull the details from the database so we have the transaction refund ID
$refQ = mysql_query("SELECT * FROM orders WHERE orders_ID = $orderID", $db);
$refC = mysql_num_rows($refQ);
if(!empty($refC)){
$refR = mysql_fetch_assoc($refQ);
$refNumber = $refR['orders_transaction_ref']; // paypal transaction ID
$FinalTotal = $refR['orders_order_total']; // order total
// paypal credentials
$apiContext = new \PayPal\Rest\ApiContext(
new \PayPal\Auth\OAuthTokenCredential(
'abc',
'xyz'
)
);
$apiContext->setConfig(array('mode' => 'live',)); // live use, not sandbox
//$amount = new Amount(); // commenting these out seemingly has no effect
//$amount->setCurrency("USD") // commenting these out seemingly has no effect
// ->setTotal($FinalTotal); // commenting these out seemingly has no effect
$refund = new Refund(); // if I comment these 2 lines out, I get "refund cannot be null"
$refund->setAmount($FinalTotal); // if I comment these 2 lines out, I get "refund cannot be null"
$sale = new Capture(); // if I comment these 2 lines out, I get "Call to a member function refund() on a non-object"
$sale->setId($refNumber); // if I comment these 2 lines out, I get "Call to a member function refund() on a non-object"
$refundRequest = new RefundRequest(); // commenting these out seemingly has no effect
$refundRequest->setAmount($FinalTotal); // commenting these out seemingly has no effect
//$captureRefund = $sale->refundCapturedPayment($refundRequest, $apiContext); // failure, error 400
try {
$sale->refund($refund, $apiContext);
//$sale->refundCapturedPayment($refund, $apiContext); // failure, error 400
} catch (Exception $ex) {
echo '<pre style="font-size:16px;">';
var_dump($ex);
echo '</pre>';
exit();
die;
}
}
2017 年 3 月 8 日更新 @12:23pm
我似乎取得了 'some' 进步,尽管我对这个词的使用不严谨。状态返回为 'completed' 但退款实际上并未发生。它也不会像示例所示那样返回父付款 ID。对此有什么想法吗?我仍在努力让它发挥作用。
这是我目前从 PayPal 获得的结果:
object(PayPal\Api\Refund)#3 (1) {
["_propMap":"PayPal\Common\PayPalModel":private]=>
array(5) {
["id"]=>
string(17) "123456789123456789"
["create_time"]=>
string(20) "2017-03-06T20:56:32Z"
["state"]=>
string(9) "completed"
["amount"]=>
object(PayPal\Api\Amount)#9 (1) {
["_propMap":"PayPal\Common\PayPalModel":private]=>
array(3) {
["total"]=>
string(4) "0.02"
["currency"]=>
string(3) "USD"
["details"]=>
object(PayPal\Api\Details)#13 (1) {
["_propMap":"PayPal\Common\PayPalModel":private]=>
array(1) {
["subtotal"]=>
string(4) "0.02"
}
}
}
}
["links"]=>
array(1) {
[0]=>
object(PayPal\Api\Links)#17 (1) {
["_propMap":"PayPal\Common\PayPalModel":private]=>
array(3) {
["href"]=>
string(59) "https://api.paypal.com/v1/payments/refund/123456789123456789"
["rel"]=>
string(4) "self"
["method"]=>
string(3) "GET"
}
}
}
}
}
下面是目前返回上述响应的代码...
require_once(dirname(__FILE__) . '/paypalSDK/autoload.php'); // require paypal files
require_once(dirname(__FILE__) . '/paypalSDK/paypal/rest-api-sdk-php/sample/bootstrap.php'); // require paypal files
require_once(dirname(__FILE__) . '/paypalSDK/paypal/rest-api-sdk-php/sample/common.php'); // require paypal files
// call required stuff
use PayPal\Api\Address;
use PayPal\Api\Amount;
use PayPal\Api\Details;
use PayPal\Api\ExecutePayment;
use PayPal\Api\FundingInstrument;
use PayPal\Api\Item;
use PayPal\Api\ItemList;
use PayPal\Api\Payer;
use PayPal\Api\Payment;
use PayPal\Api\PaymentCard;
use PayPal\Api\PaymentExecution;
use PayPal\Api\Transaction;
use PayPal\Api\Capture;
use PayPal\Api\Refund;
use PayPal\Api\RefundRequest;
use PayPal\Api\Sale;
$orderID = $_GET['order_id']; // internal order ID we wish to refund
// pull the details from database so we have the PayPal transction ID
$refQ = mysql_query("SELECT * FROM orders WHERE orders_ID = $orderID", $db);
$refC = mysql_num_rows($refQ);
if(!empty($refC)){
$refR = mysql_fetch_assoc($refQ);
$refNumber = $refR['orders_transaction_ref']; // PayPal transaction ID
// attempted 'PAY-' ID, results in "Requested resource ID was not found."
// $refNumber = $refR['orders_payment_ref']; // ex. PAY-123456789012345678901234
$FinalTotal = $refR['orders_order_total']; // order total
// paypal credentials
$apiContext = new \PayPal\Rest\ApiContext(
new \PayPal\Auth\OAuthTokenCredential(
'abc',
'xyz'
)
);
$apiContext->setConfig(array('mode' => 'live',)); // live use, not sandbox
//$amount = new Amount(); // commenting these out seemingly has no effect
//$amount->setCurrency("USD") // commenting these out seemingly has no effect
// ->setTotal($FinalTotal); // commenting these out seemingly has no effect
/*
// attempted code
// ### Refund object
$refund = new Refund();
//$refund = new RefundRequest();
$refund->setAmount($FinalTotal);
*/
$refund = new Refund();
$refund->setId($refNumber);
$refund->setSaleId($refNumber);
$refund->setAmount($FinalTotal);
$refund->setReason("Testing refund code");
//$refund->get($refNumber, $apiContext);
// Attempted code, didn't work
//
// Fatal error: Uncaught exception 'InvalidArgumentException' with message 'paymentId cannot be null' in /home/cartridgeworkspl/public_html/cfx_controllers/paypalSDK/paypal/rest-api-sdk-php/lib/PayPal/Validation/ArgumentValidator.php:25 Stack trace: #0
// $payments = Payment::get($refNumber, $apiContext);
// $payments->getTransactions();
// $obj = $payments->toJSON();//I wanted to look into the object
// $paypal_obj = json_decode($obj);//I wanted to look into the object
// $transaction_id = $paypal_obj->transactions[0]->related_resources[0]->sale->id;
// $this->refund($transaction_id);//Call your custom refund method
try {
//var_dump($refund);
$refundResponse = Refund::get($refNumber, $apiContext);
echo '<pre>';
var_dump($refundResponse);
echo '</pre>';
echo $refundResponse->getState();
echo $refundResponse->getReasonCode();
} catch (Exception $ex) {
// NOTE: PLEASE DO NOT USE RESULTPRINTER CLASS IN YOUR ORIGINAL CODE. FOR SAMPLE ONLY
ResultPrinter::printError("Get Payment", "Payment", null, null, $ex);
exit(1);
}
}
如有任何帮助,我们将不胜感激。
我认为问题在于当您提交退款时,您还必须设置 API 上下文。第一个上下文建立与 API 的连接,然后设置销售 ID。我相信您随后必须为该销售 ID 设置 API 上下文,但我不是 100%。
我设法解决了这个问题。下面是通过 REST API.
成功退还 PayPal 订单的代码
<?php
require_once(dirname(__FILE__) . '/paypalSDK/autoload.php'); // require paypal files
require_once(dirname(__FILE__) . '/paypalSDK/paypal/rest-api-sdk-php/sample/bootstrap.php'); // require paypal files
require_once(dirname(__FILE__) . '/paypalSDK/paypal/rest-api-sdk-php/sample/common.php'); // require paypal files
// call required PayPal functionality
use PayPal\Api\Address;
use PayPal\Api\Amount;
use PayPal\Api\Details;
use PayPal\Api\ExecutePayment;
use PayPal\Api\FundingInstrument;
use PayPal\Api\Item;
use PayPal\Api\ItemList;
use PayPal\Api\Payer;
use PayPal\Api\Payment;
use PayPal\Api\PaymentCard;
use PayPal\Api\PaymentExecution;
use PayPal\Api\Transaction;
use PayPal\Api\Capture;
use PayPal\Api\Refund;
use PayPal\Api\RefundRequest;
use PayPal\Api\Sale;
$orderID = $_GET['order_id']; // internal order ID we wish to refund
// pull the details from database so we have the PayPal transction ID
$refQ = mysql_query("SELECT * FROM orders WHERE orders_ID = $orderID", $db);
$refC = mysql_num_rows($refQ);
if(!empty($refC)){
$refR = mysql_fetch_assoc($refQ); // array of order data
$refNumber = $refR['orders_transaction_ref']; // PayPal transaction ID
$FinalTotal = $refR['orders_order_total']; // order total
// get PayPal access token via cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.paypal.com/v1/oauth2/token");
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Accept: application/json',
'Accept-Language: en_US'
));
curl_setopt($ch, CURLOPT_USERPWD, 'USER:PASS');
curl_setopt($ch, CURLOPT_POSTFIELDS, 'grant_type=client_credentials');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($ch);
$json = json_decode($output);
$token = $json->access_token; // this is our PayPal access token
// refund PayPal sale via cURL
$header = Array(
"Content-Type: application/json",
"Authorization: Bearer $token",
);
$ch = curl_init("https://api.paypal.com/v1/payments/sale/$refNumber/refund");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{}');
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$res = json_decode(curl_exec($ch));
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// if res has a state, retrieve it
if(isset($res->state)){
$state = $res->state;
}else{
$state = NULL; // otherwise, set to NULL
}
// if we have a state in the response...
if($state == 'completed'){
// the refund was successful
}else{
// the refund failed
$errorName = $res->name; // ex. 'Transaction Refused.'
$errorReason = $res->message; // ex. 'The requested transaction has already been fully refunded.'
}
}
?>
文档:https://developer.paypal.com/docs/api/quickstart/refund-payment/#set-the-refund-object
付款和退款使用:paypal/rest-api-sdk-php
首先,您付款时,必须填写为“sale”。
[...]
$payment = new Payment();
$payment->setIntent('sale')
->setPayer($payer)
->setRedirectUrls($redirect_urls)
->setTransactions(array($transaction));
[...]
PayPal 会return 以“paymentId”值付款,您需要保存。
退款示例。
//Previosly saved payments ID.
$paymentId = 'PI_Fv54vfd45';
//Create API connection
$apiContext = new ApiContext(new OAuthTokenCredential($paypalConf['client_id'], $paypalConf['secret']));
$apiContext->setConfig($paypalConf['settings']);
//Get sale from payment
$paypalPayment = new Payment();
$paymentInfo = $paypalPayment->get($paymentId, $apiContext);
$transactions = $paymentInfo->getTransactions();
if(empty($transactions[0])){
return false;
}
$relatedResources = $transactions[0]->getRelatedResources();
if(empty($relatedResources[0])){
return false;
}
$sale = $relatedResources[0]->getSale();
$refund = new Refund();
$amt = (new Amount())->setTotal(100)->setCurrency('EUR');
$refund->setAmount($amt);
$refund->setReason('Sale refund');
$refundedSale = $sale->refund($refund, $apiContext);
return ($refundedSale->getState() === 'completed');
遵循已接受的答案,对于那些想知道如何进行部分退款的人,而不是:
curl_setopt($ch, CURLOPT_POSTFIELDS, '{}');
您应添加这些参数:
curl_setopt($ch, CURLOPT_POSTFIELDS, '{
"amount": {
"value": "12.34",
"currency_code": "EUR"
}
}');
我正在开发一个集成到 PayPal 的 REST API 中的 PHP 应用程序。我已正确处理事务并将事务 ID 保存到 MySQL 数据库中。我现在正尝试退款,但无法让它停止给出 "Incoming JSON request does not map to API request" 错误。有人对如何让它工作有任何建议吗?
我在代码中留下了我的一些尝试,并对它们的结果进行了评论。我对让这个工作的方向感到有点迷茫。任何帮助将不胜感激。
我一直在关注位于此处的文档: https://developer.paypal.com/docs/integration/direct/payments/refund-payment/
我可能很难使该请求适应 PHP。
我找到了这段代码: https://github.com/paypal/PayPal-PHP-SDK/blob/master/sample/payments/RefundCapture.php
但它是 'requiring' 一个文件树,对于一个简单的退款请求来说似乎有点过多。
<?php
require_once(dirname(__FILE__) . '/paypalSDK/autoload.php'); // require paypal files
require_once(dirname(__FILE__) . '/paypalSDK/paypal/rest-api-sdk-php/sample/common.php'); // require paypal files
// call required stuff
use PayPal\Api\Address;
use PayPal\Api\Amount;
use PayPal\Api\Details;
use PayPal\Api\ExecutePayment;
use PayPal\Api\FundingInstrument;
use PayPal\Api\Item;
use PayPal\Api\ItemList;
use PayPal\Api\Payer;
use PayPal\Api\Payment;
use PayPal\Api\PaymentCard;
use PayPal\Api\PaymentExecution;
use PayPal\Api\Transaction;
use PayPal\Api\Capture;
use PayPal\Api\Refund;
use PayPal\Api\RefundRequest;
use PayPal\Api\Sale;
$orderID = $_GET['order_id']; // order ID we wish to refund
// pull the details from the database so we have the transaction refund ID
$refQ = mysql_query("SELECT * FROM orders WHERE orders_ID = $orderID", $db);
$refC = mysql_num_rows($refQ);
if(!empty($refC)){
$refR = mysql_fetch_assoc($refQ);
$refNumber = $refR['orders_transaction_ref']; // paypal transaction ID
$FinalTotal = $refR['orders_order_total']; // order total
// paypal credentials
$apiContext = new \PayPal\Rest\ApiContext(
new \PayPal\Auth\OAuthTokenCredential(
'abc',
'xyz'
)
);
$apiContext->setConfig(array('mode' => 'live',)); // live use, not sandbox
//$amount = new Amount(); // commenting these out seemingly has no effect
//$amount->setCurrency("USD") // commenting these out seemingly has no effect
// ->setTotal($FinalTotal); // commenting these out seemingly has no effect
$refund = new Refund(); // if I comment these 2 lines out, I get "refund cannot be null"
$refund->setAmount($FinalTotal); // if I comment these 2 lines out, I get "refund cannot be null"
$sale = new Capture(); // if I comment these 2 lines out, I get "Call to a member function refund() on a non-object"
$sale->setId($refNumber); // if I comment these 2 lines out, I get "Call to a member function refund() on a non-object"
$refundRequest = new RefundRequest(); // commenting these out seemingly has no effect
$refundRequest->setAmount($FinalTotal); // commenting these out seemingly has no effect
//$captureRefund = $sale->refundCapturedPayment($refundRequest, $apiContext); // failure, error 400
try {
$sale->refund($refund, $apiContext);
//$sale->refundCapturedPayment($refund, $apiContext); // failure, error 400
} catch (Exception $ex) {
echo '<pre style="font-size:16px;">';
var_dump($ex);
echo '</pre>';
exit();
die;
}
}
2017 年 3 月 8 日更新 @12:23pm
我似乎取得了 'some' 进步,尽管我对这个词的使用不严谨。状态返回为 'completed' 但退款实际上并未发生。它也不会像示例所示那样返回父付款 ID。对此有什么想法吗?我仍在努力让它发挥作用。
这是我目前从 PayPal 获得的结果:
object(PayPal\Api\Refund)#3 (1) {
["_propMap":"PayPal\Common\PayPalModel":private]=>
array(5) {
["id"]=>
string(17) "123456789123456789"
["create_time"]=>
string(20) "2017-03-06T20:56:32Z"
["state"]=>
string(9) "completed"
["amount"]=>
object(PayPal\Api\Amount)#9 (1) {
["_propMap":"PayPal\Common\PayPalModel":private]=>
array(3) {
["total"]=>
string(4) "0.02"
["currency"]=>
string(3) "USD"
["details"]=>
object(PayPal\Api\Details)#13 (1) {
["_propMap":"PayPal\Common\PayPalModel":private]=>
array(1) {
["subtotal"]=>
string(4) "0.02"
}
}
}
}
["links"]=>
array(1) {
[0]=>
object(PayPal\Api\Links)#17 (1) {
["_propMap":"PayPal\Common\PayPalModel":private]=>
array(3) {
["href"]=>
string(59) "https://api.paypal.com/v1/payments/refund/123456789123456789"
["rel"]=>
string(4) "self"
["method"]=>
string(3) "GET"
}
}
}
}
}
下面是目前返回上述响应的代码...
require_once(dirname(__FILE__) . '/paypalSDK/autoload.php'); // require paypal files
require_once(dirname(__FILE__) . '/paypalSDK/paypal/rest-api-sdk-php/sample/bootstrap.php'); // require paypal files
require_once(dirname(__FILE__) . '/paypalSDK/paypal/rest-api-sdk-php/sample/common.php'); // require paypal files
// call required stuff
use PayPal\Api\Address;
use PayPal\Api\Amount;
use PayPal\Api\Details;
use PayPal\Api\ExecutePayment;
use PayPal\Api\FundingInstrument;
use PayPal\Api\Item;
use PayPal\Api\ItemList;
use PayPal\Api\Payer;
use PayPal\Api\Payment;
use PayPal\Api\PaymentCard;
use PayPal\Api\PaymentExecution;
use PayPal\Api\Transaction;
use PayPal\Api\Capture;
use PayPal\Api\Refund;
use PayPal\Api\RefundRequest;
use PayPal\Api\Sale;
$orderID = $_GET['order_id']; // internal order ID we wish to refund
// pull the details from database so we have the PayPal transction ID
$refQ = mysql_query("SELECT * FROM orders WHERE orders_ID = $orderID", $db);
$refC = mysql_num_rows($refQ);
if(!empty($refC)){
$refR = mysql_fetch_assoc($refQ);
$refNumber = $refR['orders_transaction_ref']; // PayPal transaction ID
// attempted 'PAY-' ID, results in "Requested resource ID was not found."
// $refNumber = $refR['orders_payment_ref']; // ex. PAY-123456789012345678901234
$FinalTotal = $refR['orders_order_total']; // order total
// paypal credentials
$apiContext = new \PayPal\Rest\ApiContext(
new \PayPal\Auth\OAuthTokenCredential(
'abc',
'xyz'
)
);
$apiContext->setConfig(array('mode' => 'live',)); // live use, not sandbox
//$amount = new Amount(); // commenting these out seemingly has no effect
//$amount->setCurrency("USD") // commenting these out seemingly has no effect
// ->setTotal($FinalTotal); // commenting these out seemingly has no effect
/*
// attempted code
// ### Refund object
$refund = new Refund();
//$refund = new RefundRequest();
$refund->setAmount($FinalTotal);
*/
$refund = new Refund();
$refund->setId($refNumber);
$refund->setSaleId($refNumber);
$refund->setAmount($FinalTotal);
$refund->setReason("Testing refund code");
//$refund->get($refNumber, $apiContext);
// Attempted code, didn't work
//
// Fatal error: Uncaught exception 'InvalidArgumentException' with message 'paymentId cannot be null' in /home/cartridgeworkspl/public_html/cfx_controllers/paypalSDK/paypal/rest-api-sdk-php/lib/PayPal/Validation/ArgumentValidator.php:25 Stack trace: #0
// $payments = Payment::get($refNumber, $apiContext);
// $payments->getTransactions();
// $obj = $payments->toJSON();//I wanted to look into the object
// $paypal_obj = json_decode($obj);//I wanted to look into the object
// $transaction_id = $paypal_obj->transactions[0]->related_resources[0]->sale->id;
// $this->refund($transaction_id);//Call your custom refund method
try {
//var_dump($refund);
$refundResponse = Refund::get($refNumber, $apiContext);
echo '<pre>';
var_dump($refundResponse);
echo '</pre>';
echo $refundResponse->getState();
echo $refundResponse->getReasonCode();
} catch (Exception $ex) {
// NOTE: PLEASE DO NOT USE RESULTPRINTER CLASS IN YOUR ORIGINAL CODE. FOR SAMPLE ONLY
ResultPrinter::printError("Get Payment", "Payment", null, null, $ex);
exit(1);
}
}
如有任何帮助,我们将不胜感激。
我认为问题在于当您提交退款时,您还必须设置 API 上下文。第一个上下文建立与 API 的连接,然后设置销售 ID。我相信您随后必须为该销售 ID 设置 API 上下文,但我不是 100%。
我设法解决了这个问题。下面是通过 REST API.
成功退还 PayPal 订单的代码<?php
require_once(dirname(__FILE__) . '/paypalSDK/autoload.php'); // require paypal files
require_once(dirname(__FILE__) . '/paypalSDK/paypal/rest-api-sdk-php/sample/bootstrap.php'); // require paypal files
require_once(dirname(__FILE__) . '/paypalSDK/paypal/rest-api-sdk-php/sample/common.php'); // require paypal files
// call required PayPal functionality
use PayPal\Api\Address;
use PayPal\Api\Amount;
use PayPal\Api\Details;
use PayPal\Api\ExecutePayment;
use PayPal\Api\FundingInstrument;
use PayPal\Api\Item;
use PayPal\Api\ItemList;
use PayPal\Api\Payer;
use PayPal\Api\Payment;
use PayPal\Api\PaymentCard;
use PayPal\Api\PaymentExecution;
use PayPal\Api\Transaction;
use PayPal\Api\Capture;
use PayPal\Api\Refund;
use PayPal\Api\RefundRequest;
use PayPal\Api\Sale;
$orderID = $_GET['order_id']; // internal order ID we wish to refund
// pull the details from database so we have the PayPal transction ID
$refQ = mysql_query("SELECT * FROM orders WHERE orders_ID = $orderID", $db);
$refC = mysql_num_rows($refQ);
if(!empty($refC)){
$refR = mysql_fetch_assoc($refQ); // array of order data
$refNumber = $refR['orders_transaction_ref']; // PayPal transaction ID
$FinalTotal = $refR['orders_order_total']; // order total
// get PayPal access token via cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.paypal.com/v1/oauth2/token");
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Accept: application/json',
'Accept-Language: en_US'
));
curl_setopt($ch, CURLOPT_USERPWD, 'USER:PASS');
curl_setopt($ch, CURLOPT_POSTFIELDS, 'grant_type=client_credentials');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($ch);
$json = json_decode($output);
$token = $json->access_token; // this is our PayPal access token
// refund PayPal sale via cURL
$header = Array(
"Content-Type: application/json",
"Authorization: Bearer $token",
);
$ch = curl_init("https://api.paypal.com/v1/payments/sale/$refNumber/refund");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{}');
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$res = json_decode(curl_exec($ch));
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// if res has a state, retrieve it
if(isset($res->state)){
$state = $res->state;
}else{
$state = NULL; // otherwise, set to NULL
}
// if we have a state in the response...
if($state == 'completed'){
// the refund was successful
}else{
// the refund failed
$errorName = $res->name; // ex. 'Transaction Refused.'
$errorReason = $res->message; // ex. 'The requested transaction has already been fully refunded.'
}
}
?>
文档:https://developer.paypal.com/docs/api/quickstart/refund-payment/#set-the-refund-object
付款和退款使用:paypal/rest-api-sdk-php
首先,您付款时,必须填写为“sale”。
[...]
$payment = new Payment();
$payment->setIntent('sale')
->setPayer($payer)
->setRedirectUrls($redirect_urls)
->setTransactions(array($transaction));
[...]
PayPal 会return 以“paymentId”值付款,您需要保存。
退款示例。
//Previosly saved payments ID.
$paymentId = 'PI_Fv54vfd45';
//Create API connection
$apiContext = new ApiContext(new OAuthTokenCredential($paypalConf['client_id'], $paypalConf['secret']));
$apiContext->setConfig($paypalConf['settings']);
//Get sale from payment
$paypalPayment = new Payment();
$paymentInfo = $paypalPayment->get($paymentId, $apiContext);
$transactions = $paymentInfo->getTransactions();
if(empty($transactions[0])){
return false;
}
$relatedResources = $transactions[0]->getRelatedResources();
if(empty($relatedResources[0])){
return false;
}
$sale = $relatedResources[0]->getSale();
$refund = new Refund();
$amt = (new Amount())->setTotal(100)->setCurrency('EUR');
$refund->setAmount($amt);
$refund->setReason('Sale refund');
$refundedSale = $sale->refund($refund, $apiContext);
return ($refundedSale->getState() === 'completed');
遵循已接受的答案,对于那些想知道如何进行部分退款的人,而不是:
curl_setopt($ch, CURLOPT_POSTFIELDS, '{}');
您应添加这些参数:
curl_setopt($ch, CURLOPT_POSTFIELDS, '{
"amount": {
"value": "12.34",
"currency_code": "EUR"
}
}');