首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用退款?

使用退款?
EN

Stack Overflow用户
提问于 2017-03-03 21:31:21
回答 4查看 3.9K关注 0票数 2

我正在开发一个PHP应用程序,它集成到PayPal的REST中。事务处理正确,并将事务ID保存到MySQL数据库中。我现在试图退款出售,但不能让它停止提供一个“传入的JSON请求不映射到API请求”错误。有没有人对如何做到这一点有任何建议?

我在代码中留下了一些尝试,并对它们的结果进行了评论。我觉得有点迷失了方向。任何帮助都将不胜感激。

我一直在跟踪这里的文档:https://developer.paypal.com/docs/integration/direct/payments/refund-payment/

我可能很难使这个请求适应PHP。

我找到了这段代码:https://github.com/paypal/PayPal-PHP-SDK/blob/master/sample/payments/RefundCapture.php

但是对于一个简单的退款请求来说,它需要一棵文件树,这看起来有点过分。

代码语言:javascript
运行
复制
<?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;
    }
}

更新3/8/2017 @12:23

我似乎已经取得了一些进展,虽然我使用的术语松散。州返回为“已完成”,但退款并没有实际发生。它也没有返回父付款ID,就像示例演示的那样。对此有什么想法吗?我还在努力让这件事起作用。

这就是我目前从PayPal获得的结果:

代码语言:javascript
运行
复制
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"
        }
      }
    }
  }
}

下面是当前返回上述响应的代码.

代码语言:javascript
运行
复制
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
    // https://stackoverflow.com/questions/18927591/paypal-api-how-to-get-sale-id-and-refund-payment-made-via-paypal
    // 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);
    }

}

任何帮助都会受到极大的感谢。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-03-08 20:21:46

我设法熬过去了。下面是通过REST成功地退还PayPal订单的代码。

代码语言:javascript
运行
复制
<?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.'
        }
    }
?>
票数 0
EN

Stack Overflow用户

发布于 2020-06-05 12:32:45

文档:https://developer.paypal.com/docs/api/quickstart/refund-payment/#set-the-refund-object

付款及退款用途:paypal/rest-api-sdk-php

首先,当你付款时,它必须是"sale“。

代码语言:javascript
运行
复制
[...]
$payment = new Payment();
$payment->setIntent('sale')
    ->setPayer($payer)
    ->setRedirectUrls($redirect_urls)
    ->setTransactions(array($transaction));
[...]

PayPal将返回带有"paymentId“值的付款,您需要保存它。

退款的例子。

代码语言:javascript
运行
复制
//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');
票数 4
EN

Stack Overflow用户

发布于 2017-03-06 16:28:10

我相信问题是,当您提交退款时,您还必须设置API上下文。第一个上下文建立与API的连接,然后设置销售ID,我相信您必须为该销售ID设置API上下文,但我不是100%。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42588772

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档