PayPal API:如何获取销售ID并通过PayPal退款付款?

7
我正在使用PHP中的PayPal API来创建交易,包括信用卡和通过PayPal本身。此外,我需要能够退款这些交易。我使用的代码大部分都是直接从PayPal API示例中复制的,对于信用卡交易可以正常工作,但是对于PayPal交易则失败了。具体而言,我尝试通过Payment对象深入挖掘并提取该销售的ID。通过信用卡进行付款的Payment对象包含RelatedResources对象,而RelatedResources对象又包含带有ID的Sale对象,但是通过PayPal进行付款的Payment对象似乎不包含它们。因此,我的问题是,如何从通过PayPal进行的付款中检索Sale ID?
以下是使用存储的信用卡创建付款的方法:
    $creditCardToken = new CreditCardToken();
$creditCardToken->setCreditCardId('CARD-2WG5320481993380UKI5FSFI');

// ### FundingInstrument
// A resource representing a Payer's funding instrument.
// For stored credit card payments, set the CreditCardToken
// field on this object.
$fi = new FundingInstrument();
$fi->setCreditCardToken($creditCardToken);

// ### Payer
// A resource representing a Payer that funds a payment
// For stored credit card payments, set payment method
// to 'credit_card'.
$payer = new Payer();
$payer->setPaymentMethod("credit_card")
    ->setFundingInstruments(array($fi));

// ### Amount
// Lets you specify a payment amount.
// You can also specify additional details
// such as shipping, tax.
$amount = new Amount();
$amount->setCurrency("USD")
    ->setTotal('1.00');

// ### Transaction
// A transaction defines the contract of a
// payment - what is the payment for and who
// is fulfilling it. 
$transaction = new Transaction();
$transaction->setAmount($amount)
    ->setDescription("Payment description");

// ### Payment
// A Payment Resource; create one using
// the above types and intent set to 'sale'
$payment = new Payment();
$payment->setIntent("sale")
    ->setPayer($payer)
    ->setTransactions(array($transaction));

// ###Create Payment
// Create a payment by calling the 'create' method
// passing it a valid apiContext.
// (See bootstrap.php for more on `ApiContext`)
// The return object contains the state.
try {
    $payment->create($apiContext);
} catch (PayPal\Exception\PPConnectionException $ex) {
    error_log($ex->getMessage());
    error_log(print_r($ex->getData(), true));
}

相比之下,以下是我如何进行 PayPal 支付的流程。它是一个两步骤的过程。首先用户会被导向到 PayPal 的网站,然后当他们回到我的网站时,支付将被处理。
$payer = new Payer();
$payer->setPaymentMethod("paypal");

$amount = new Amount();
$amount->setCurrency("USD")
    ->setTotal($userInfo['amount']);

$transaction = new Transaction();
$transaction->setAmount($amount)
    ->setDescription("Payment description");

// ### Redirect urls
// Set the urls that the buyer must be redirected to after 
// payment approval/ cancellation.
$baseUrl = 'http://example.com';
$redirectUrls = new RedirectUrls();
$redirectUrls->setReturnUrl("$baseUrl/?success=true")
    ->setCancelUrl("$baseUrl/?success=false");

$payment = new Payment();
$payment->setIntent("sale")
    ->setPayer($payer)
    ->setRedirectUrls($redirectUrls)
    ->setTransactions(array($transaction));

try {
    $payment->create($apiContext);
} catch (PayPal\Exception\PPConnectionException $ex) {
    error_log($ex->getMessage());
    error_log(print_r($ex->getData(), true));
    return;
}

// ### Get redirect url
// The API response provides the url that you must redirect
// the buyer to. Retrieve the url from the $payment->getLinks()
// method
foreach($payment->getLinks() as $link) {
    if($link->getRel() == 'approval_url') {
        $redirectUrl = $link->getHref();
        break;
    }
}

// ### Redirect buyer to PayPal website
// Save payment id so that you can 'complete' the payment
// once the buyer approves the payment and is redirected
// bacl to your website.
//
// It is not really a great idea to store the payment id
// in the session. In a real world app, you may want to 
// store the payment id in a database.
$_SESSION['paymentId'] = $payment->getId();

if(isset($redirectUrl)) {
    $response->redirectUrl = $redirectUrl;
}
return $response;

以下是第二部分,当用户被重定向到我的网站并收到“成功”消息时:

$payment = Payment::get($lineitem->paypal_payment_ID, $apiContext);

// PaymentExecution object includes information necessary 
// to execute a PayPal account payment. 
// The payer_id is added to the request query parameters
// when the user is redirected from paypal back to your site
$execution = new PaymentExecution();
$execution->setPayer_id($_GET['PayerID']);

//Execute the payment
// (See bootstrap.php for more on `ApiContext`)
$payment->execute($execution, $apiContext);

下面是我如何退款的过程。API示例中没有讨论如何检索销售ID,因此我会通过对象进行钻取。通过PayPal进行的付款没有RelatedResources对象,因此操作失败:

    try {
    $payment = Payment::get('PAY-8TB50937RV8840649KI6N33Y', $apiContext);
    $transactions = $payment->getTransactions();
    $resources = $transactions[0]->getRelatedResources();//This DOESN'T work for PayPal transactions.

    $sale = $resources[0]->getSale();
    $saleID = $sale->getId();

    // ### Refund amount
    // Includes both the refunded amount (to Payer) 
    // and refunded fee (to Payee). Use the $amt->details
    // field to mention fees refund details.
    $amt = new Amount();
    $amt->setCurrency('USD')
        ->setTotal($lineitem->cost);

    // ### Refund object
    $refund = new Refund();
    $refund->setAmount($amt);

    // ###Sale
    // A sale transaction.
    // Create a Sale object with the
    // given sale transaction id.
    $sale = new Sale();
    $sale->setId($saleID);
    try {   
        // Refund the sale
        // (See bootstrap.php for more on `ApiContext`)
        $sale->refund($refund, $apiContext);
    } catch (PayPal\Exception\PPConnectionException $ex) {
        error_log($ex->getMessage());
        error_log(print_r($ex->getData(), true));
        return;
    }
} catch (PayPal\Exception\PPConnectionException $ex) {
    error_log($ex->getMessage());
    error_log(print_r($ex->getData(), true));
    return;
}

有没有想法如何检索销售ID?谢谢!

你确定支付('PAY-8TB50937RV8840649KI6N33Y')已经执行了吗?只有当支付达到“已完成”状态时,才会创建销售记录,而这只有在支付被执行时才会发生。对于PayPal支付,直到此时,支付状态要么是“已创建”要么是“已批准”。 - aydiv
PayPal的一位工作人员刚刚确认,使用PayPal进行的付款是不可退款的,因此无法实现。 - user2801042
这是一篇关于通过php api进行退款的文章。http://www.kvcodes.com/2016/05/paypal-refund-transaction/ - Kvvaradha
2个回答

9

我成功地退款了一笔交易,但没有找到一种简单的方法。因此,我采用了另一种方式。请尝试以下代码:

$apiContext = new ApiContext(new OAuthTokenCredential(
            "<CLIENT_ID>", "<CLIENT_SECRET>")
    );
    $payments = Payment::get("PAY-44674747470TKNYKRLI", $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

Cheers!


$transaction_ref是什么意思?它是$transaction_id吗?@Jubayer Arefin - Dev DOS
1
是的,$transaction_id实际上是唯一的销售ID。已更新答案。 - Jubayer Arefin

1
功能Payment::get()没有返回所有所需信息。 您需要对由executePayment()函数返回的对象应用getTransactions()getRelatedResources()函数。
.....
$payment = executePayment( $execution, $apiContext );
$transactions = $payment->getTransactions();
$resources = $transactions[0]->getRelatedResources();
.....

2
哎呀,getRelatedResources 函数引发了一个未定义的索引错误,真是太喜欢这个 API 了 :-) 错误信息为 Undefined index: related_resources,位于 \paypal\paypal\sdk-core-php\lib\PayPal\Common\PPModel.php 的第 14 行。 - dave

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接