PayPal-smart-payment-buttons

简介Smart Payment Buttons(智能支付按钮),是全球著名在线支付商PayPal提供的一项最新收款功能,其目的是尽可能多的消除结账中产生的摩擦(checkout friction),即:影响买家完成支付的不利因素。其集成图如下 可以看到,Smart Payment Buttons已经将paypal和信用卡支付集成到了页面中,实际上是在js中做了封装,点击不同的支付类型,调用不同的支付。在付款时,浏览器会在当前结账页面弹出一个小窗口来引导用户完成支付,这样用户就无需离开当前的购物页面。和之前的付款方式相比,这应该也是一个改进。 付款流程 You add the PayPal Smart Payment Buttons to your web page.Your buyer clicks the button.The button calls PayPal Orders API to set up a transaction.The button launches the PayPal Checkout experience.The buyer approves the payment.The button calls PayPal Orders API to finalize the transaction.You show a confirmation to your buyer.整个付款过程都在js中调用完成 整合到代码中<head> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta http-equiv="X-UA-Compatible" content="IE=edge" /></head><body> <script src="https://www.paypal.com/sdk/js?client-id=SB_CLIENT_ID"> </script></body>注:SB_CLIENT_ID是自己在PayPal账户中创建APP时获取的client_id,默认sb。 ...

May 18, 2019 · 1 min · jiezi

Laravel中集成PayPal

最近在写一个面向国外买家的一个商城项目,既然面向国外,那就要用到PayPal这个支付平台。因为在对接PayPal的过程中遇到了一些问题,花费了一些时间,所以把对接的过程记下来,也希望能帮助到用到PayPal的朋友。 我集成的是paypal/rest-api-sdk-php。PayPal的api有 v1和v2两个版本,我用的这个是v1版本。 以下皆以代码的形式展现,没有截图,但我尽量用代码讲解明白。假设你已经有了用laravel写的一个项目:Step:1安装扩展包composer require paypal/rest-api-sdk-phpStep:2创建paypal.php配置文件在Config目录新建paypal.php配置文件,内容如下return [ ‘paypal’ => [ /** set your paypal credential / ‘client_id’ =>‘paypal client_id’, ‘secret’ => ‘paypal secret ID’, / * SDK 配置 / ‘settings’ => array( /* * 沙盒测试’sandbox’ 或者 ’live’ / ‘mode’ => ‘sandbox’, /* * 请求超时时间 / ‘http.ConnectionTimeOut’ => 1000, /* * 是否开启日志:true开启,false不开启 / ’log.LogEnabled’ => true, /* * 日志存储的文件 / ’log.FileName’ => storage_path() . ‘/logs/paypal.log’, /* * 日志级别 ‘DEBUG’, ‘INFO’, ‘WARN’ or ‘ERROR’ * / ’log.LogLevel’ => ‘INFO’ ), ], ‘2checkout’ => [ // ]];Step:3创建路由 // 第一步:显示表单,这是一个简单的表单页面,我们把金额输入,然后点击提交 Route::get(‘paypal-form’, ‘Payment\PayPalController@payPalShow’)->name(‘paypal-form’); // 第二步:第一步提交后发送请求,请求该方法,该方法用于创建订单,创建支付流程 Route::post(‘paypal-pay’, ‘Payment\PayPalController@pay’)->name(‘payment.paypay.pay’); // 第三步:异步回调 Route::post(‘paypal-notify’, ‘Payment\PayPalController@payPalNotify’)->name(‘payment.paypal.notify’); // 第三步:前端回调 Route::get(‘paypal-return’, ‘Payment\PayPalController@payPalReturn’)->name(‘payment.paypal.return’); // 第三步:取消 Route::get(‘paypal-cancel’, ‘Payment\PayPalController@payPalCancel’)->name(‘payment.paypal.cancel’);Step:3创建控制器<?phpnamespace App\Http\Controllers\Payment;use App\Http\Controllers\BaseController;use Illuminate\Http\Request;use Illuminate\Support\Facades\Input;use PayPal\Api\Amount;use PayPal\Api\Item;use PayPal\Api\ItemList;use PayPal\Api\Payer;use PayPal\Api\Payment;use PayPal\Api\PaymentExecution;use PayPal\Api\RedirectUrls;use PayPal\Api\Transaction;use PayPal\Auth\OAuthTokenCredential;use PayPal\Rest\ApiContext;class PayPalController extends BaseController{ private $_api_context; public function __construct() { $payPal_config = config(‘payment.payPal’); // 初始化 PayPal Api context $this->_api_context = new ApiContext(new OAuthTokenCredential( $payPal_config[‘client_id’], $payPal_config[‘secret’] )); $this->_api_context->setConfig($payPal_config[‘setting’]); } // 显示表单 public function payPalShow() { return view(‘payment.paypal’); } // 第二步,请求这里 public function pay(Request $request) { $payer = new Payer(); $payer->setPaymentMethod(‘paypal’); // 产品名称,币种,数量,单个产品金额 $item1 = new Item(); $item1->setName(‘item1’) ->setCurrency(‘USD’) ->setQuantity(1) ->setPrice($request->get(‘amount’)); // 将所有产品集合到 ItemList中 $item_list = new ItemList(); $item_list->setItems([$item1]); $amount = new Amount(); $amount->setCurrency(‘USD’) ->setTotal($request->get(‘amount’)); // 生成交易 $transaction = new Transaction(); $transaction->setAmount($amount) ->setItemList($item_list) ->setDescription(‘你的交易’) ->setNotifyUrl(route(’notify_url’)) // 注意,这里设置异步回调地址 ->setInvoiceNumber($order->order_number); // 这里设置订单号 // 设置前端回调地址和取消支付地址 $redirect_urls = new RedirectUrls(); $redirect_urls->setReturnUrl(route(‘payment.paypal.cancel’)) ->setCancelUrl(route(‘payment.paypal.cancel’)); $payment = new Payment(); $payment->setIntent(‘Sale’) ->setPayer($payer) ->setRedirectUrls($redirect_urls) ->setTransactions(array($transaction)); try { // 这里生成支付流程 $payment->create($this->_api_context); } catch (\PayPal\Exception\PayPalConnectionException $ex) { if (config(‘app.debug’)) { session()->put(’error’,‘Connection timeout’); return redirect()->route(‘paypal-form’); /* echo “Exception: " . $ex->getMessage() . PHP_EOL; / / $err_data = json_decode($ex->getData(), true); / / exit; **/ } else { session()->put(’error’,‘Some error occur, sorry for inconvenient’); return redirect()->route(‘paypal-form’); } } foreach($payment->getLinks() as $link) { if($link->getRel() == ‘approval_url’) { $redirect_url = $link->getHref(); break; } } // $payment->getId()得到的是支付流水号 session()->put(‘paypal_payment_id’, $payment->getId()); if(isset($redirect_url)) { // 跳转到支付页面 return redirect()->away($redirect_url); } session()->put(’error’,‘Unknown error occurred’); return session()->route(‘paypal-form’); } public function payPalReturn(Request $request) { // 支付成功后,在前端页面跳转回来时,url地址中会带有paymentID 和 PayerID $payment_id = session()->get(‘paypal_payment_id’); session()->forget(‘paypal_payment_id’); if (empty(Input::get(‘PayerID’)) || empty(Input::get(’token’))) { session()->put(’error’,‘Payment failed’); return redirect()->route(‘paypal-form’); } $payment = Payment::get($payment_id, $this->_api_context); $execution = new PaymentExecution(); $execution->setPayerId(Input::get(‘PayerID’)); $result = $payment->execute($execution, $this->_api_context); // 当拿到的状态时approved表示支付成功 if ($result->getState() == ‘approved’) { session()->put(‘success’,‘Payment success’); return redirect()->route(‘paypal-form’); } session()->put(’error’,‘Payment failed’); return redirect()->route(‘paypal-form’); } public function payPalNotify() { Log::info(12312, Input::get()); // 这里写我们的业务逻辑,订单状态更新,物流信息等等. }}Step:4创建表单<form class=“form-horizontal” method=“POST” id=“payment-form” role=“form” action=”{!! URL::route(‘paypal-pay’) !!}" > {{ csrf_field() }} <div class=“form-group{{ $errors->has(‘amount’) ? ’ has-error’ : ’’ }}"> <label for=“amount” class=“col-md-4 control-label”>Amount</label> <div class=“col-md-6”> <input id=“amount” type=“text” class=“form-control” name=“amount” value=”{{ old(‘amount’) }}" autofocus> @if ($errors->has(‘amount’)) <span class=“help-block”> <strong>{{ $errors->first(‘amount’) }}</strong> </span> @endif </div> </div> <div class=“form-group”> <div class=“col-md-6 col-md-offset-4”> <button type=“submit” class=“btn btn-primary”> Paywith Paypal </button> </div> </div></form>以上既是我做商城项目时PayPal的对接流程,因为英语不好的问题,开发起来会出现很多问题,如果英文好,想知道更多的用法,可以看PayPal的开发者文档,还有demo演示。 ...

April 18, 2019 · 2 min · jiezi