PayPal
PayPal, 全球眾多用戶使用的國際貿易支付工具, 能夠輕鬆完成境外收取款項!一個帳戶全球通用, 成為PayPal商家, 就能在任何地方接受更多付款方式。
下載paypal sdk
在composer.json 中加入“paypal/rest-api-sdk-php” : “1.7.4”,如圖:
執行composer update
#註冊開發者帳號,建立測試應用,測試帳戶
位址:
https://developer.paypal.com
建立沙盒測試帳號
帳號後台(可以看到自己的消費記錄):
https://www.sandbox.paypal.com/signin?returnUri=https%3A%2F%2Fwww.sandbox.paypal.com%2Fmyaccount%2Fsummary&state=%2F
建立應用程式
#查看應用程式設定
點擊建立的應用,查看設定Client ID,Secret,後面請求介面需要用到,sandbox為測試環境,live為線上環境
新測試帳號
可設定金額及密碼
接入代碼
下單一邏輯
<?php namespace App\Http\Controllers\Api; use Illuminate\Http\Request; use App\Http\Controllers\Controller; use PayPal\Api\Payer; use PayPal\Api\Item; use PayPal\Api\ItemList; use PayPal\Api\Details; use PayPal\Api\Amount; use PayPal\Api\Transaction; use PayPal\Api\RedirectUrls; use PayPal\Api\Payment; use PayPal\Auth\OAuthTokenCredential; use PayPal\Exception\PayPalConnectionException; use PayPal\Rest\ApiContext; use PayPal\Api\PaymentExecution; class paypalController extends Controller { const clientId = 'xxxxxxxxx';//应用Client ID const clientSecret = 'xxxxxxxx';//Secret const accept_url = 'http://xxx.laravel.com/Api/paypal/Callback'; //支付成功和取消交易的跳转地址 const Currency = 'USD';//货币单位 protected $PayPal; public function __construct() { $this->PayPal = new ApiContext( new OAuthTokenCredential( self::clientId, self::clientSecret ) ); //如果是沙盒测试环境不设置,请注释掉 // $this->PayPal->setConfig( // array( // 'mode' => 'live', // ) // ); } /** * @param * $product 商品 * $price 价钱 * $shipping 运费 * $description 描述内容 */ public function pay() { $product = '1123'; $price = 1; $shipping = 0; $description = '1123123'; $paypal = $this->PayPal; $total = $price + $shipping;//总价 $payer = new Payer(); $payer->setPaymentMethod('paypal'); $item = new Item(); $item->setName($product)->setCurrency(self::Currency)->setQuantity(1)->setPrice($price); $itemList = new ItemList(); $itemList->setItems([$item]); $details = new Details(); $details->setShipping($shipping)->setSubtotal($price); $amount = new Amount(); $amount->setCurrency(self::Currency)->setTotal($total)->setDetails($details); $transaction = new Transaction(); $transaction->setAmount($amount)->setItemList($itemList)->setDescription($description)->setInvoiceNumber(uniqid()); $redirectUrls = new RedirectUrls(); $redirectUrls->setReturnUrl(self::accept_url . '?success=true')->setCancelUrl(self::accept_url . '/?success=false'); $payment = new Payment(); $payment->setIntent('sale')->setPayer($payer)->setRedirectUrls($redirectUrls)->setTransactions([$transaction]); try { $payment->create($paypal); } catch (PayPalConnectionException $e) { echo $e->getData(); die(); } $approvalUrl = $payment->getApprovalLink(); header("Location: {$approvalUrl}"); }
走完下單邏輯會跳到paypal的支付頁面,第一次需要輸入帳號密碼,如圖:
進入付款頁面,選擇Paypal餘額支付,付款完成或取消交易會自動跳到你下單時傳的跳轉地址,並會傳兩個參數paymentId(paypal訂單號),PayerID(用戶id),你可以根據你的業務邏輯寫對應邏輯,一般同步回調確認用戶是否付款,異步回調處理業務邏輯
同步回呼
/** * 回调 */ public function Callback() { $success = trim($_GET['success']); if ($success == 'false' && !isset($_GET['paymentId']) && !isset($_GET['PayerID'])) { echo '取消付款';die; } $paymentId = trim($_GET['paymentId']); $PayerID = trim($_GET['PayerID']); if (!isset($success, $paymentId, $PayerID)) { echo '支付失败';die; } if ((bool)$_GET['success'] === 'false') { echo '支付失败,支付ID【' . $paymentId . '】,支付人ID【' . $PayerID . '】';die; } $payment = Payment::get($paymentId, $this->PayPal); $execute = new PaymentExecution(); $execute->setPayerId($PayerID); try { $payment->execute($execute, $this->PayPal); } catch (Exception $e) { echo ',支付失败,支付ID【' . $paymentId . '】,支付人ID【' . $PayerID . '】';die; } echo '支付成功,支付ID【' . $paymentId . '】,支付人ID【' . $PayerID . '】';die; }
非同步回呼
回呼位址配置在後台,位址必須為https開頭,設定一般過一段時間才會生效(我是下午申請,第二天上午才生效的,如圖:
你可以勾選很多事件發送通知,不過最重要的還是支付完成(Payment sale completed)以及退款(Payment sale refunded)
支付完成##
public function notify(){ //获取回调结果 $json_data = $this->get_JsonData(); if(!empty($json_data)){ Log::debug("paypal notify info:\r\n".json_encode($json_data)); }else{ Log::debug("paypal notify fail:参加为空"); } //自己打印$json_data的值看有那些是你业务上用到的 //比如我用到 $data['invoice'] = $json_data['resource']['invoice_number']; $data['txn_id'] = $json_data['resource']['id']; $data['total'] = $json_data['resource']['amount']['total']; $data['status'] = isset($json_data['status'])?$json_data['status']:''; $data['state'] = $json_data['resource']['state']; try { //处理相关业务 } catch (\Exception $e) { //记录错误日志 Log::error("paypal notify fail:".$e->getMessage()); return "fail"; } return "success"; } public function get_JsonData(){ $json = file_get_contents('php://input'); if ($json) { $json = str_replace("'", '', $json); $json = json_decode($json,true); } return $json; }##處理退款
public function returnMoney()
{
try {
$txn_id = "xxxxxxx"; //异步加调中拿到的id
$amt = new Amount();
$amt->setCurrency('USD')
->setTotal('99'); // 退款的费用
$refund = new Refund();
$refund->setAmount($amt);
$sale = new Sale();
$sale->setId($txn_id);
$refundedSale = $sale->refund($refund, $this->PayPal);
} catch (\Exception $e) {
// PayPal无效退款
return json_decode(json_encode(['message' => $e->getMessage(), 'code' => $e->getCode(), 'state' => $e->getMessage()])); // to object
}
// 退款完成
return $refundedSale;
}
總結
paypal對於擴展海外支付的業務還是很有幫助的,它支援多種貨幣,可綁定各種信用卡,銀行卡,缺點是接入時不會有paypal技術人員和你對接,反正我是在接入完成之後才聯繫到paypal對接人的,還好接入難度不大,網路資料比較豐富,希望這篇文章可以給各位帶來幫助,對於海外支付有興趣的可以和我來討論。
相關教學推薦:《
laravel》
以上是詳解Laravel接入paypal支付的詳細內容。更多資訊請關注PHP中文網其他相關文章!