摘要:最近在寫(xiě)一個(gè)面向國(guó)外買(mǎi)家的一個(gè)商城項(xiàng)目,既然面向國(guó)外,那就要用到這個(gè)支付平臺(tái)。因?yàn)樵趯?duì)接的過(guò)程中遇到了一些問(wèn)題,花費(fèi)了一些時(shí)間,所以把對(duì)接的過(guò)程記下來(lái),也希望能幫助到用到的朋友。以下皆以代碼的形式展現(xiàn),沒(méi)有截圖,但我盡量用代碼講解明白。
最近在寫(xiě)一個(gè)面向國(guó)外買(mǎi)家的一個(gè)商城項(xiàng)目,既然面向國(guó)外,那就要用到PayPal這個(gè)支付平臺(tái)。因?yàn)樵趯?duì)接PayPal的過(guò)程中遇到了一些問(wèn)題,花費(fèi)了一些時(shí)間,所以把對(duì)接的過(guò)程記下來(lái),也希望能幫助到用到PayPal的朋友。
我集成的是paypal/rest-api-sdk-php。PayPal的api有 v1和v2兩個(gè)版本,我用的這個(gè)是v1版本。
以下皆以代碼的形式展現(xiàn),沒(méi)有截圖,但我盡量用代碼講解明白。
假設(shè)你已經(jīng)有了用laravel寫(xiě)的一個(gè)項(xiàng)目:
composer require paypal/rest-api-sdk-phpStep:2創(chuàng)建payment.php配置文件
在Config目錄新建payment.php配置文件,內(nèi)容如下
return [ "paypal" => [ /** set your paypal credential **/ "client_id" =>"paypal client_id", "secret" => "paypal secret ID", /** * SDK 配置 */ "settings" => array( /** * 沙盒測(cè)試"sandbox" 或者 "live" */ "mode" => "sandbox", /** * 請(qǐng)求超時(shí)時(shí)間 */ "http.ConnectionTimeOut" => 1000, /** * 是否開(kāi)啟日志:true開(kāi)啟,false不開(kāi)啟 */ "log.LogEnabled" => true, /** * 日志存儲(chǔ)的文件 */ "log.FileName" => storage_path() . "/logs/paypal.log", /** * 日志級(jí)別 "DEBUG", "INFO", "WARN" or "ERROR" * */ "log.LogLevel" => "INFO" ), ], "2checkout" => [ // ] ];Step:3創(chuàng)建路由
// 第一步:顯示表單,這是一個(gè)簡(jiǎn)單的表單頁(yè)面,我們把金額輸入,然后點(diǎn)擊提交 Route::get("paypal-form", "PaymentPayPalController@payPalShow")->name("paypal-form"); // 第二步:第一步提交后發(fā)送請(qǐng)求,請(qǐng)求該方法,該方法用于創(chuàng)建訂單,創(chuàng)建支付流程 Route::post("paypal-pay", "PaymentPayPalController@pay")->name("payment.paypay.pay"); // 第三步:異步回調(diào) Route::post("paypal-notify", "PaymentPayPalController@payPalNotify")->name("payment.paypal.notify"); // 第三步:前端回調(diào) Route::get("paypal-return", "PaymentPayPalController@payPalReturn")->name("payment.paypal.return"); // 第三步:取消 Route::get("paypal-cancel", "PaymentPayPalController@payPalCancel")->name("payment.paypal.cancel");Step:3創(chuàng)建控制器
_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"); } // 第二步,請(qǐng)求這里 public function pay(Request $request) { $payer = new Payer(); $payer->setPaymentMethod("paypal"); // 產(chǎn)品名稱,幣種,數(shù)量,單個(gè)產(chǎn)品金額 $item1 = new Item(); $item1->setName("item1") ->setCurrency("USD") ->setQuantity(1) ->setPrice($request->get("amount")); // 將所有產(chǎn)品集合到 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")) // 注意,這里設(shè)置異步回調(diào)地址 ->setInvoiceNumber($order->order_number); // 這里設(shè)置訂單號(hào) // 設(shè)置前端回調(diào)地址和取消支付地址 $redirect_urls = new RedirectUrls(); $redirect_urls->setReturnUrl(route("payment.paypal.return")) ->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 (PayPalExceptionPayPalConnectionException $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()得到的是支付流水號(hào) session()->put("paypal_payment_id", $payment->getId()); if(isset($redirect_url)) { // 跳轉(zhuǎn)到支付頁(yè)面 return redirect()->away($redirect_url); } session()->put("error","Unknown error occurred"); return session()->route("paypal-form"); } public function payPalReturn(Request $request) { // 支付成功后,在前端頁(yè)面跳轉(zhuǎn)回來(lái)時(shí),url地址中會(huì)帶有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); // 當(dāng)拿到的狀態(tài)時(shí)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()); // 這里寫(xiě)我們的業(yè)務(wù)邏輯,訂單狀態(tài)更新,物流信息等等. } }Step:4創(chuàng)建表單
以上既是我做商城項(xiàng)目時(shí)PayPal的對(duì)接流程,因?yàn)橛⒄Z(yǔ)不好的問(wèn)題,開(kāi)發(fā)起來(lái)會(huì)出現(xiàn)很多問(wèn)題,
如果英文好,想知道更多的用法,可以看PayPal的開(kāi)發(fā)者文檔,還有demo演示。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/31266.html
摘要:原文地址不知道是不是有和我一樣使用到聯(lián)想懂得物聯(lián)網(wǎng)卡的兄。戳這里以下是使用說(shuō)明此擴(kuò)展是聯(lián)想的,可以方便的在中集成。由于聯(lián)想懂得的接口還在開(kāi)發(fā)中,所以這個(gè)擴(kuò)展包將處于開(kāi)發(fā)階段,等穩(wěn)定之后會(huì)發(fā)布版本。 原文地址 不知道是不是有和我一樣使用到聯(lián)想懂得物聯(lián)網(wǎng)卡的兄dei。我將接口封裝成了laravel框架的擴(kuò)展,也可以在laravel之外的項(xiàng)目中使用。 github戳這里 以下是使用說(shuō)明: 此...
摘要:本文非原創(chuàng),基于學(xué)院在中使用實(shí)現(xiàn)文件導(dǎo)入導(dǎo)出功能這篇文章在實(shí)際中測(cè)試調(diào)整。簡(jiǎn)介在中集成套件中的,從而方便我們以優(yōu)雅的富有表現(xiàn)力的代碼實(shí)現(xiàn)文件的導(dǎo)入和導(dǎo)出。 本文非原創(chuàng),基于laravel 學(xué)院《在 Laravel 5 中使用 Laravel Excel 實(shí)現(xiàn) Excel/CSV 文件導(dǎo)入導(dǎo)出功能》 這篇文章在實(shí)際中測(cè)試調(diào)整。 showImg(https://segmentfault.c...
摘要:中異常處理類主要包含兩個(gè)方法和,其中就是主要用來(lái)向第三方發(fā)送異常報(bào)告,這里選擇向這個(gè)神器發(fā)送異常報(bào)告,并使用通知開(kāi)發(fā)人員。通過(guò)也能發(fā)現(xiàn)的執(zhí)行流程。 說(shuō)明:Laravel學(xué)習(xí)筆記之bootstrap源碼解析中聊異常處理時(shí)提到過(guò)Sentry這個(gè)神器,并打算以后聊聊這款神器,本文主要就介紹這款Errors Tracking神器Sentry,Sentry官網(wǎng)有一句話個(gè)人覺(jué)得帥呆了: Stop ...
摘要:因?yàn)檫@對(duì)于一個(gè)剛參加工作的工程師來(lái)說(shuō),這有可能就是一月和一個(gè)月的區(qū)別了。多編寫(xiě)網(wǎng)站編程說(shuō)到底其實(shí)也就是一門(mén)手藝,就對(duì)于智商差不多的程序員來(lái)說(shuō),技藝的高超程度往往就在于練的多少了。 利益相關(guān):以下的所有文字都是僅代表個(gè)人觀點(diǎn),不代表全組織的利益。 本人就是一大三狗,自學(xué)PHP時(shí)間已經(jīng)快兩年了,感覺(jué)自己還是一個(gè)入門(mén)級(jí)的選手。說(shuō)說(shuō)自己是如何一步步走過(guò)來(lái)的。 1. 官方文檔 對(duì),我還是堅(jiān)...
摘要:也就是說(shuō)在中,我們的代碼是要在環(huán)境中運(yùn)行。而在中,是沒(méi)有等以及的,即所有的框架都是不可以使用的。比如相關(guān)組件,相關(guān)組件,等都不能在中引用。是可以在中使用的。 接著第一彈講,我們已經(jīng)搭建好一個(gè)屬于自己的weex項(xiàng)目了,然后如何開(kāi)發(fā)呢?由于之前項(xiàng)目中都是采用vue全家桶進(jìn)行開(kāi)發(fā),路由使用vue-router插件,狀態(tài)管理使用vuex,Ajax前后臺(tái)交互使用axios,圖標(biāo)庫(kù)使用font-a...
閱讀 2141·2023-04-25 18:49
閱讀 1846·2019-08-30 14:02
閱讀 2646·2019-08-29 17:24
閱讀 3328·2019-08-28 18:10
閱讀 2929·2019-08-28 18:03
閱讀 492·2019-08-26 12:01
閱讀 3312·2019-08-26 11:31
閱讀 1424·2019-08-26 10:29