iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 19
1
Software Development

PHP新手30天實戰金流系列 第 19

[Day19]平台串金流--PAYPAL (中)

  • 分享至 

  • xImage
  •  
PHP新手30天實戰金流, Laravel6

前言

Integration steps

  1. Required Set up your development environment.
  2. Required Create PayPal payment.
  3. Required Get payment approval.
  4. Required Execute payment.
  5. Optional Search payment details.

Step 1 Set up your development environment

  • 建立測試用的sandbox帳號
    • 進去 Manage Account 編輯姓名
      https://ithelp.ithome.com.tw/upload/images/20191004/20102155b1cjjRstPM.png

Step 2 Create PayPal payment

  • 主要需要自行設定:

    $redirectUrls->setReturnUrl("http://e0102c5b.ngrok.io/payment/website/PaypalExec")
    ->setCancelUrl("https://example.com/your_cancel_url.html");
    

    setReturnUrl 為買家 approval 成功後轉導的路由。

  • 程式碼如下:

<?php

// 1. Autoload the SDK Package. This will include all the files and classes to your autoloader
// require __DIR__  . '/../vendor/autoload.php';
include('vendor/autoload.php');
use PayPal\Api\Item;
use PayPal\Api\ItemList;
use PayPal\Api\Details;

// 2. Provide your Secret Key. Replace the given one with your app clientId, and Secret
// https://developer.paypal.com/webapps/developer/applications/myapps
$apiContext = new \PayPal\Rest\ApiContext(
    new \PayPal\Auth\OAuthTokenCredential(
        'AUvyf-GcLIYKxkpfIPQ5gcGzKjwlPodvQvyww5OU4iwpLUTXlcy9dZq_t91toX1XE4-PR1oH2KA2h22A',     // ClientID
        'EHIwO_yPRI_-8UY6olHCFuU2_9nh03qbFA1sGEomkYA-HAd2KgjogCBYUHMzoNPwThh1DNxS_PRNgulS'      // ClientSecret
        
    )
);

// 3. Lets try to create a Payment
// https://developer.paypal.com/docs/api/payments/#payment_create
$payer = new \PayPal\Api\Payer();
$payer->setPaymentMethod('paypal');

$item1 = new Item();
$item1->setName('Vegan drink')
    ->setCurrency('USD')
    ->setQuantity(1)
    ->setPrice(7.5);
$item2 = new Item();
$item2->setName('Vegan pizza')
    ->setCurrency('USD')
    ->setQuantity(5)
    ->setPrice(2);
$item3 = new Item();
$item3->setName('Vegan cake')
    ->setCurrency('USD')
    ->setQuantity(10)
    ->setPrice(1);


$itemList = new ItemList();
$itemList->setItems(array($item1, $item2, $item3));

$details = new Details();
$details->setShipping(1.2)
    ->setTax(1.3)
    ->setSubtotal(27.50);

$amount = new \PayPal\Api\Amount();
$amount->setCurrency("USD")
    ->setTotal(30)
    ->setDetails($details);



$transaction = new \PayPal\Api\Transaction();
$transaction->setAmount($amount);
$transaction->setItemList($itemList);


$redirectUrls = new \PayPal\Api\RedirectUrls();
$redirectUrls->setReturnUrl("http://e0102c5b.ngrok.io/payment/website/PaypalExec")
    ->setCancelUrl("https://example.com/your_cancel_url.html");

$payment = new \PayPal\Api\Payment();
$payment->setIntent('sale')
    ->setPayer($payer)
    ->setTransactions(array($transaction))
    ->setRedirectUrls($redirectUrls);


// 4. Make a Create Call and print the values
try {
    $payment->create($apiContext);
    echo $payment;

    echo "\n\nRedirect user to approval_url: " . $payment->getApprovalLink() . "\n";
}
catch (\PayPal\Exception\PayPalConnectionException $ex) {
    // This will print the detailed information on the exception.
    //REALLY HELPFUL FOR DEBUGGING
    echo $ex->getData();
}

Step 3 Get payment approval

  • setReturnUrl 為買家 approval 成功後轉導的路由。我們會在這個路由下寫 Execute Payment 函式。
    因此我們在 web.app 中 開一支 api
Route::get('payment/website/PaypalExec', 'PaymentController@PaypalExec')->name('payment.website.PaypalExec');

Step 4 Execute payment

  • 主要需要自行設定:
$clientId = ~~~
$clientSecret = ~~~

目前都先 Hard code 上去
* clientId 在 Myapp 頁面

  • https://ithelp.ithome.com.tw/upload/images/20191004/20102155ViYz2dpLVo.png

  • 程式碼如下:

public function PaypalExec(Request $request)
{
    // require __DIR__ . '/../bootstrap.php';
    $clientId = 'AUvyf-GcLIYKxkpfIPQ5gcGzKjwlPodvQvyww5OU4iwpLUTXlcy9dZq_t91toX1XE4-PR1oH2KA2h22A';
    $clientSecret = 'EHIwO_yPRI_-8UY6olHCFuU2_9nh03qbFA1sGEomkYA-HAd2KgjogCBYUHMzoNPwThh1DNxS_PRNgulS';

    $apiContext = getApiContext($clientId, $clientSecret);
    include('ResultPrinter_by.php');


    $out = new \Symfony\Component\Console\Output\ConsoleOutput();
    $data = $request->all();
    $out->writeln("data: ".json_encode($data['paymentId']));

    $paymentId = $_GET['paymentId'];
    $payment = Payment::get($paymentId, $apiContext);
    $execution = new PaymentExecution();
    $execution->setPayerId($_GET['PayerID']);

        try {
            $result = $payment->execute($execution, $apiContext);
            ResultPrinter_by::printResult("Executed Payment", "Payment", $payment->getId(), $execution, $result);

            try {
                $payment = Payment::get($paymentId, $apiContext);
            } catch (Exception $ex) {
                // NOTE: PLEASE DO NOT USE RESULTPRINTER CLASS IN YOUR ORIGINAL CODE. FOR SAMPLE ONLY
                ResultPrinter_by::printError("Get Payment", "Payment", null, null, $ex);
                exit(1);
            }
        } catch (Exception $ex) {
            // NOTE: PLEASE DO NOT USE RESULTPRINTER CLASS IN YOUR ORIGINAL CODE. FOR SAMPLE ONLY
            ResultPrinter_by::printError("Executed Payment", "Payment", null, null, $ex);
            exit(1);
        }
        ResultPrinter_by::printResult("Get Payment", "Payment", $payment->getId(), null, $payment);

        return $payment;
}

Step 5 Search payment details

  • 我們執行以下指令來取得 access token :
    curl -v https://api.sandbox.paypal.com/v1/oauth2/token \
    -H "Accept: application/json" \
    -H "Accept-Language: en_US" \
    -u "client_id:secret" \
    -d "grant_type=client_credentials"
    

    得:A21AAHVj4RelUTlaftxanx1tJ35VIHH7vjaRT8VVPVwo3O8zkQKPQoO_siGVuuUiENYdXtwCCQIoox6RoOaIYfSt0eXN55Rqw

  • 接著可以執行以下指令來查看 payment details
curl -v -X GET https://api.sandbox.paypal.com/v1/payments/payment/PAYID-LWLMWMI5HN03256BG9682119 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer A21AAHVj4RelUTlaftxanx1tJ35VIHH7vjaRT8VVPVwo3O8zkQKPQoO_siGVuuUiENYdXtwCCQIoox6RoOaIYfSt0eXN55Rqw"

得:

{"id":"PAYID-LWLMWMI5HN03256BG9682119","intent":"sale","state":"approved","cart":"8XX37253EJ240105U","payer":{"payment_method":"paypal","status":"VERIFIED","payer_info":{"email":"sb-3074747322463@personal.example.com","first_name":"ErinYing","last_name":"Cheng","payer_id":"WZL3D9344Z5LG","shipping_address":{"recipient_name":"ErinYing Cheng","line1":"1 Main St","city":"San Jose","state":"CA","postal_code":"95131","country_code":"US"},"phone":"4084191500","country_code":"US"}},"transactions":[{"amount":{"total":"30.00","currency":"USD","details":{"subtotal":"27.50","tax":"1.30","shipping":"1.20","insurance":"0.00","handling_fee":"0.00","shipping_discount":"0.00"}},"payee":{"merchant_id":"L9HBWYGB3ZQ8L","email":"sb-xrgox330311@business.example.com"},"description":"Ground Coffee 40 oz","item_list":{"items":[{"name":"Ground Coffee 40 oz","price":"7.50","currency":"USD","tax":"0.00","quantity":1},{"name":"Granola bars","price":"2.00","currency":"USD","tax":"0.00","quantity":5},{"name":"Vegan cake","price":"1.00","currency":"USD","tax":"0.00","quantity":10}],"shipping_address":{"recipient_name":"ErinYing Cheng","line1":"1 Main St","city":"San Jose","state":"CA","postal_code":"95131","country_code":"US"}},"related_resources":[{"sale":{"id":"0J529360JM853904K","state":"pending","amount":{"total":"30.00","currency":"USD","details":{"subtotal":"27.50","tax":"1.30","shipping":"1.20","insurance":"0.00","handling_fee":"0.00","shipping_discount":"0.00"}},"payment_mode":"INSTANT_TRANSFER","reason_code":"PAYMENT_REVIEW","protection_eligibility":"INELIGIBLE","transaction_fee":{"value":"1.17","currency":"USD"},"parent_payment":"PAYID-LWLMWMI5HN03256BG9682119","create_time":"2019-10-04T06:53:46Z","update_time":"2019-10-04T06:53:46Z","links":[{"href":"https://api.sandbox.paypal.com/v1/payments/sale/0J529360JM853904K","rel":"self","method":"GET"},{"href":"https://api.sandbox.paypal.com/v1/payments/sale/0J529360JM853904K/refund","rel":"refund","method":"POST"},{"href":"https://api.sandbox.paypal.com/v1/payments/payment/PAYID-LWLMWMI5HN03256BG9682119","rel":"parent_payment","method":"GET"}]}}]}],"create_time":"2019-10-04T04:31:45Z","update_time":"2019-10-04T06:53:46Z","links":[{"href":"https://api.sandbox.paypal.com/v1/payments/payment/PAYID-LWLMWMI5HN03256BG9682119","rel":"self","method":"GET"}]}

https://ithelp.ithome.com.tw/upload/images/20191004/20102155PfHtsFJwGf.png

  • 商家不是收到 30元, 因為paypal 會收費
    https://ithelp.ithome.com.tw/upload/images/20191004/20102155UpyR7bTJEL.png




上一篇
[Day18]平台串金流--PAYPAL 簡介
下一篇
[Day20]平台串金流--PAYPAL 導入平台,架構重整
系列文
PHP新手30天實戰金流34
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言