Stripe支付介紹在asp.net mvc中開發(fā)對接街州,圖文加代碼說明

最近一個國外的電商項目,需要對接支付功能玻孟,國內(nèi)的支付一般使用微信支付唆缴、支付寶、銀聯(lián)等等黍翎,但國際上一般使用Paypal面徽、Skrill、BrainTree匣掸、Stripe等趟紊,經(jīng)過內(nèi)部綜合考量所以最后選擇使用 Stripe支付。

Stripe的對接相對還是比較簡單的碰酝,只是相關(guān)的文檔是英文的霎匈,且國內(nèi)和國外的思想不一樣,看文檔不是很方便送爸。

做為技術(shù)人員這里我將對接中所遇到的問題和解決方法匯總铛嘱,希望能對開發(fā)人員有所幫助。

一:Stripe支付介紹

Stripe支付國際支付還是非常有名氣的袭厂,具體的介紹下面的一些說明:

中文官網(wǎng):https://stripe.com/zh-cn-us

Stripe國際支付簡介:點擊打開

Stripe支付對接還是非常方便的墨吓。

Stripe支付功能也還是很強大的包括支付、賬單纹磺、訂閱等等帖烘。

二:Stripe技術(shù)對接

對接前的準備工作

需要去官網(wǎng)申請一個賬號,好像是國內(nèi)的銀行卡不好申請橄杨。具體如何申請還請百度搜索下秘症,我這里就不贅述了。

申請好以后在后臺拿到測試的公鑰和私鑰讥珍。

需要申請HTTPS證書历极,這個異步通知的接口需要提供HTTPS的域名。

官網(wǎng)接口文檔衷佃,共區(qū)分后端趟卸、前端、ios和安卓氏义。

后端的接口:點擊查看

前端的接口:點擊查看

其它的一些使用文檔:點擊查看

支付對接方式說明:共有2中方式锄列。

方式一:使用Stripe的支付頁面進行支付(官方名稱:CheckOut)。

這種分2種情況:

跳轉(zhuǎn)到Stripe的支付頁面進行支付惯悠,這種類似于支付寶的對接邻邮,需要跳轉(zhuǎn)到支付寶的支付頁面。Stripe的支付頁面效果圖如下克婶。

自己的頁面構(gòu)建一個Stripe的支付筒严,這種類似于微信公眾號的支付丹泉。

方式二:自己做支付頁面,通過接口的方式進行支付鸭蛙。

官網(wǎng)給出了很多HTML示例效果摹恨,可下載后自己修改下。點擊查看示例效果

采用這種方式娶视,輸入信用卡等信息是Stripe通過js控制的晒哄,我們是拿不到用戶輸入的相關(guān)信息的,為了安全肪获。

不管是使用方式一和方式二寝凌,我們都無法獲取用戶輸入的信用卡等信息。

推薦使用方式一對接孝赫,有以下幾點:

用戶在Stripe輸入銀行卡信息较木,用戶感覺要更加安全。

減少不必要的開發(fā)工作寒锚,因為自己做的收銀頁面沒法和Stripe的比較劫映。

下面所有的流程主要是使用跳轉(zhuǎn)到Stripe支付頁面支付。

簡單的流程說明

用戶點擊頁面上的“支付”按鈕刹前。

通過js調(diào)用后臺的接口泳赋,接口中要調(diào)用Stripe的接口創(chuàng)建支付的會話(Session),調(diào)用Stripe接口之前需要設(shè)置一些數(shù)據(jù)喇喉,包括支付金額祖今、支付方式等等,這個后面說明拣技。調(diào)用接口成功則Stripe會返回一個SessionId千诬,將該值返會給前端。

前端拿到SessionId以后膏斤,帶上改參數(shù)跳轉(zhuǎn)到Stripe的支付頁面徐绑。

用戶如果取消支付或支付成功,則跳轉(zhuǎn)到創(chuàng)建Session配置的取消地址和支付成功跳轉(zhuǎn)地址莫辨。

支付成功或其他的一些事件傲茄,Stripe會異步通知我們支付結(jié)果。

上面這幾步驟是大致的流程沮榜,還請有多的細節(jié)問題盘榨。

下面我們根據(jù)上面簡單的流程進行一步步詳細的說明。

下面的演示代碼是:.NET MVC

三:發(fā)起支付

官網(wǎng)有個快速開始支付的說明文檔蟆融,點擊查看

做一個HTML頁面草巡,頁面上需要引用Stripe的js文件和點擊跳轉(zhuǎn)到支付按鈕。當然支付的頁面上還有很多其他的一些東西型酥,比如收貨地址山憨、商品信息等等查乒。

<!DOCTYPE html>

<html>

<head>

? ? <meta charset="utf-8" />

? ? <title></title>

? ? <script src="~/js/jquery-1.12.4.min.js"></script>

? ? <script src="http://js.stripe.com/v3/"></script>

</head>

<body>

? <button id="checkout-button">去付款</button>

? ? <script type="text/javascript">

? ? ? ? //創(chuàng)建一個stripe,里面的參數(shù)則是stripe申請的公鑰萍歉,在后臺能查看到侣颂,pk_開通的档桃,加test表示是測試的

? ? ? ? var stripe = Stripe('pk_test_xxx'); //輸入自己的pk_test

? ? ? ? var checkoutButton = document.getElementById('checkout-button');

? ? ? ? //支付按鈕點擊事件

? ? ? ? checkoutButton.addEventListener('click', function () {

? ? ? ? ? ? //調(diào)用后端的接口

? ? ? ? ? ? fetch('/home/CreateCheckoutSession', {

? ? ? ? ? ? ? ? method: 'POST',

? ? ? ? ? ? })

? ? ? ? ? ? ? ? .then(function (response) {

? ? ? ? ? ? ? ? ? ? return response.json();

? ? ? ? ? ? ? ? })

? ? ? ? ? ? ? ? .then(function (session) {

? ? ? ? ? ? ? ? ? ? //調(diào)用后端接口成功枪孩,得到sessionId,頁面會在函數(shù)里面進行跳轉(zhuǎn)

? ? ? ? ? ? ? ? ? ? return stripe.redirectToCheckout({ sessionId: session.id });

? ? ? ? ? ? ? ? })

? ? ? ? ? ? ? ? .then(function (result) {


? ? ? ? ? ? ? ? ? ? if (result.error) {

? ? ? ? ? ? ? ? ? ? ? ? alert(result.error.message);

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? })

? ? ? ? ? ? ? ? .catch(function (error) {

? ? ? ? ? ? ? ? ? ? console.error('Error:', error);

? ? ? ? ? ? ? ? });

? ? ? ? });

? ? </script>

</body>

</html>

上面的頁面中需要一個后臺調(diào)用Stripe來產(chǎn)生SessionId藻肄。

后端代碼蔑舞,VS上先在NuGet上引用第三方的包,名稱:Stripe.net嘹屯。

后端提供SessionId的代碼如下

? ? ? /// <summary>

? ? ? ? /// 調(diào)用stripe創(chuàng)建支付的會話攻询,成功則返回會話的Id,用于頁面跳轉(zhuǎn)

? ? ? ? /// </summary>

? ? ? ? /// <returns></returns>

? ? ? ? [HttpPost]

? ? ? ? public ActionResult CreateCheckoutSession()

? ? ? ? {

? ? ? ? ? ? try

? ? ? ? ? ? {

? ? ? ? ? ? ? ? // Stripe的私鑰州弟,在 Stripe后臺能看到 sk開頭的钧栖,_test則表示是用于測試環(huán)境的。

? ? ? ? ? ? ? ? StripeConfiguration.ApiKey = "sk_test_xx"; //sk_test_xxx 這里需要修改

? ? ? ? ? ? ? ? //封裝支付請求的數(shù)據(jù)婆翔,

? ? ? ? ? ? ? ? //字段說明詳見官網(wǎng):https://stripe.com/docs/api/checkout/sessions/object

? ? ? ? ? ? ? ? var options = new SessionCreateOptions

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? PaymentMethodTypes = new List<string>

? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? "card" ,"alipay"? //支持的付款方式

? ? ? ? ? ? ? ? ? ? },

? ? ? ? ? ? ? ? ? ? BillingAddressCollection= "required",//是否要收集帳單地址信息

? ? ? ? ? ? ? ? ? ? LineItems = new List<SessionLineItemOptions>

? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? new SessionLineItemOptions

? ? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? PriceData = new SessionLineItemPriceDataOptions

? ? ? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? ? UnitAmount = 2000, //需要支付的金額

? ? ? ? ? ? ? ? ? ? ? ? ? Currency = "usd",//支持的貨幣簡寫拯杠,具體見官網(wǎng)

? ? ? ? ? ? ? ? ? ? ? ? ? ProductData = new SessionLineItemPriceDataProductDataOptions

? ? ? ? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? ? ? Name = "支付的顯示名稱,或者是商品名稱",

? ? ? ? ? ? ? ? ? ? ? ? ? ? Images= new List<string>(){"http://www.angelasp.com/images/angellogo.gif" },

? ? ? ? ? ? ? ? ? ? ? ? ? ? Description="支付的描述信息啃奴,可以是商品的描述等信息"

? ? ? ? ? ? ? ? ? ? ? ? ? },

? ? ? ? ? ? ? ? ? ? ? ? },

? ? ? ? ? ? ? ? ? ? ? ? Quantity = 1,

? ? ? ? ? ? ? ? ? ? ? },

? ? ? ? ? ? ? ? ? ? },


? ? ? ? ? ? ? ? ? ? Mode = "payment",

? ? ? ? ? ? ? ? ? ? SuccessUrl = "https://example.com/success", //支付成功以后跳轉(zhuǎn)的URL地址

? ? ? ? ? ? ? ? ? ? CancelUrl = "https://example.com/cancel",//用戶取消支付以后跳轉(zhuǎn)的URL地址

? ? ? ? ? ? ? ? };

? ? ? ? ? ? ? ? options.PaymentIntentData = new SessionPaymentIntentDataOptions();

? ? ? ? ? ? ? ? options.PaymentIntentData.Metadata = new Dictionary<string, string>

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? { "sn", "6735" }, { "attachmentValue", "6735" },? //傳遞的自定義參數(shù)潭陪,回調(diào)通知的時候會原樣返回

? ? ? ? ? ? ? ? };

? ? ? ? ? ? ? ? var service = new SessionService();

? ? ? ? ? ? ? ? Session session = service.Create(options);

? ? ? ? ? ? ? ? return Json(new { id = session.Id });

? ? ? ? ? ? }

? ? ? ? ? ? catch (Exception ex)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? throw ex;

? ? ? ? ? ? }

? ? ? ? }

上面前端HTML和后端的接口都處理好以后,點擊頁面上的那個去付款的按鈕最蕾,則會跳轉(zhuǎn)到Stripe的收銀臺頁面(下圖)依溯。

Stripe的測試也非常方便,官方提供了很多測試的卡號瘟则,下面表格是我收集整理的一些黎炉。

卡號

品牌

CVC

年月

4242424242424242

Visa

任意3位數(shù)字

大于當前時間的年月

4000056655665556

Visa (debit)

任意3位數(shù)字

大于當前時間的年月

5555555555554444

Mastercard

任意3位數(shù)字

大于當前時間的年月

2223003122003222

Mastercard (2-series)

任意3位數(shù)字

大于當前時間的年月

5200828282828210

Mastercard (debit)

任意3位數(shù)字

大于當前時間的年月

5105105105105100

Mastercard (prepaid)

任意3位數(shù)字

大于當前時間的年月

378282246310005

American Express

任意4位數(shù)字

大于當前時間的年月

371449635398431

American Express

任意4位數(shù)字

大于當前時間的年月

6011111111111117

Discover

任意3位數(shù)字

大于當前時間的年月

6011000990139424

Discover

任意3位數(shù)字

大于當前時間的年月

3056930009020004

Diners Club

任意3位數(shù)字

大于當前時間的年月

36227206271667

Diners Club (14 digit card)

任意3位數(shù)字

大于當前時間的年月

3566002020360505

JCB

任意3位數(shù)字

大于當前時間的年月

6200000000000005

UnionPay

任意3位數(shù)字

大于當前時間的年月

信用卡的年月,填寫大于當前時間的年月即可醋拧。

在Stripe的支付頁面填寫好相關(guān)信息以后點擊支付慷嗜,如果沒有問題的話就會支付成功。

支付成功以后可在Stripe的后臺看到付款的金額和一些日志趁仙,日志包括事件洪添、接口請求日志、訂單數(shù)據(jù)等等雀费。因為是測試的數(shù)據(jù)所以要先開啟可查看測試數(shù)據(jù)干奢,不然是看不到的,如何開啟看下圖盏袄。

完成上面的步驟以后忿峻,則發(fā)起支付收款簡單的流程沒有問題下薄啥,下面說下如何接受Stripe異步通知。

四:接受異步通知

Stripe支持很多事件的通知逛尚,例如Session創(chuàng)建完成垄惧、訂單付款完成、退款等等绰寞,詳見官網(wǎng)說明到逊。事件類型說明

需要一個HTTPS的接口,如果沒有證書可去阿里云等申請免費的證書滤钱。Windows如何安裝HTTPS證書觉壶?

在Stripe后臺添加一個端點(接受通知的配置)見下圖

事件類型非常多,目前我們是做跳轉(zhuǎn)支付件缸,支付成功了通知我們铜靶,則選擇:payment_intent.succeeded? 事件

拿到驗證端點的密鑰,每個端點有獨立的密鑰他炊,見下圖

編寫接受通知的接口代碼争剿,官網(wǎng)有英文的說明代碼,下面我把代碼整理了貼出來痊末。

? ? ? ? /// <summary>

? ? ? ? /// 支付成功的異步通知接口

? ? ? ? /// </summary>

? ? ? ? /// <returns></returns>

? ? ? ? [HttpPost]

? ? ? ? public ActionResult Notify()

? ? ? ? {

? ? ? ? ? ? var json = new StreamReader(HttpContext.Request.InputStream).ReadToEndAsync().Result;

? ? ? ? ? ? try

? ? ? ? ? ? {

? ? ? ? ? ? ? ? //驗證數(shù)據(jù)的來源

? ? ? ? ? ? ? ? string endpointSecret = "whsec_XXXXX";//后臺創(chuàng)建的端點簽名密鑰

? ? ? ? ? ? ? ? var stripeEvent = EventUtility.ConstructEvent(json, Request.Headers["Stripe-Signature"], endpointSecret);

? ? ? ? ? ? ? ? //stripeEvent.Type? 則是不同的事件蚕苇,具體則看你配置端點的時候,這個接口設(shè)置了那些事件

? ? ? ? ? ? ? ? if (stripeEvent.Type == Events.PaymentIntentSucceeded)

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? //支付成功的業(yè)務處理

? ? ? ? ? ? ? ? ? ? var payModel = stripeEvent.Data.Object as PaymentIntent;

? ? ? ? ? ? ? ? ? ? decimal payAmount = payModel.Amount / 100M;? //支付的金額

? ? ? ? ? ? ? ? ? ? string payPaySN = payModel.Id;//支付方的唯一訂單號

? ? ? ? ? ? ? ? ? ? string payCurrency = payModel.Currency;//支付的貨幣

? ? ? ? ? ? ? ? ? ? //賬單信息舌胶,如果創(chuàng)建Session的時候設(shè)置收集賬單信息捆蜀,則這里可以獲取到

? ? ? ? ? ? ? ? ? ? var billing = payModel.Charges.Data[0].BillingDetails;

? ? ? ? ? ? ? ? ? ? string billingName = billing.Name;

? ? ? ? ? ? ? ? ? ? string billingEmail = billing.Email;

? ? ? ? ? ? ? ? ? ? string billingPhone = billing.Phone;

? ? ? ? ? ? ? ? ? ? string billingCity = billing.Address.City;

? ? ? ? ? ? ? ? ? ? string billingCountry = billing.Address.Country;

? ? ? ? ? ? ? ? ? ? string billingLine1 = billing.Address.Line1;

? ? ? ? ? ? ? ? ? ? string billingLine2 = billing.Address.Line2;

? ? ? ? ? ? ? ? ? ? string billingPostalCode = billing.Address.PostalCode;

? ? ? ? ? ? ? ? ? ? string billingState = billing.Address.State;

? ? ? ? ? ? ? ? ? ? //發(fā)起支付創(chuàng)建的自定義參數(shù),這里具體根據(jù)自己的業(yè)務來

? ? ? ? ? ? ? ? ? ? string orderSN = payModel.Metadata["sn"];

? ? ? ? ? ? ? ? ? ? string attachmentValue = payModel.Metadata["attachmentValue"];

? ? ? ? ? ? ? ? ? ? //其它的一些業(yè)務處理幔嫂,比如更新訂單狀態(tài)等等

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? else if (stripeEvent.Type == Events.PaymentMethodAttached)

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? var paymentMethod = stripeEvent.Data.Object as PaymentMethod;

? ? ? ? ? ? ? ? ? ? Console.WriteLine("PaymentMethod was attached to a Customer!");

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? else

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? Console.WriteLine("Unhandled event type: {0}", stripeEvent.Type);

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? return Json(new { id = 1});

? ? ? ? ? ? }

? ? ? ? ? ? catch (StripeException)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? return Json(new { id =2 });

? ? ? ? ? ? }

? ? ? ? }

完成上面的步驟辆它,就可以測試發(fā)起支付了和接受支付結(jié)果了。

Stripe后臺可以看到請求的日志記錄履恩,可以針對端點發(fā)送測試數(shù)據(jù)锰茉,這些對于調(diào)試程序還是很方便的,具體如何使用我就不多說了切心,都有中文的大家用心看下就懂了飒筑。

上線的時候需要將相關(guān)配置參數(shù)換成正式環(huán)境的。

以上只是我在研究Stripe支付的一點簡單的總結(jié)绽昏,時間倉促很多細節(jié)還未深入詳細說明协屡。以上如有不正之處還望見諒,可給我留言討論全谤,謝謝肤晓!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子补憾,更是在濱河造成了極大的恐慌漫萄,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件盈匾,死亡現(xiàn)場離奇詭異腾务,居然都是意外死亡,警方通過查閱死者的電腦和手機削饵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門岩瘦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人葵孤,你說我怎么就攤上這事担钮。” “怎么了尤仍?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長狭姨。 經(jīng)常有香客問我宰啦,道長,這世上最難降的妖魔是什么饼拍? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任赡模,我火速辦了婚禮,結(jié)果婚禮上师抄,老公的妹妹穿的比我還像新娘漓柑。我一直安慰自己,他們只是感情好叨吮,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布辆布。 她就那樣靜靜地躺著,像睡著了一般茶鉴。 火紅的嫁衣襯著肌膚如雪锋玲。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天涵叮,我揣著相機與錄音惭蹂,去河邊找鬼。 笑死割粮,一個胖子當著我的面吹牛盾碗,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播舀瓢,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼廷雅,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起榜轿,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤幽歼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后谬盐,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體甸私,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年飞傀,在試婚紗的時候發(fā)現(xiàn)自己被綠了皇型。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡砸烦,死狀恐怖弃鸦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情幢痘,我是刑警寧澤唬格,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站颜说,受9級特大地震影響购岗,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜门粪,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一喊积、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧玄妈,春花似錦乾吻、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至瞭郑,卻和暖如春辜御,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背屈张。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工擒权, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人阁谆。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓碳抄,卻偏偏與公主長得像,于是被迫代替她去往敵國和親场绿。 傳聞我的和親對象是個殘疾皇子剖效,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容