摘要:標(biāo)準(zhǔn)是為了最大限度保護(hù)持卡人數(shù)據(jù)的一套標(biāo)準(zhǔn)。實(shí)現(xiàn)符合標(biāo)準(zhǔn)的支付,有兩種方式加載的托管表單使用的托管表單,加載方便,安全性高,但是用戶定制程度不高,只能稍微改改表單樣式,可以使用自己設(shè)計(jì)的表單,調(diào)用做安全性校驗(yàn)和數(shù)據(jù)發(fā)送接收。
PCI 標(biāo)準(zhǔn)是為了最大限度保護(hù)持卡人數(shù)據(jù)的一套標(biāo)準(zhǔn)。要求很多,可以看 PCI標(biāo)準(zhǔn) 站點(diǎn)了解。對(duì)于程序猿來(lái)說(shuō),要保證的是用戶的任何支付信息,都不走自己的服務(wù)器,不保存在自己的數(shù)據(jù)庫(kù)。
實(shí)現(xiàn)符合PCI標(biāo)準(zhǔn)的支付,有兩種方式
加載Authorize.net的托管表單
使用AcceptJs
Authorize.net的托管表單,加載方便,安全性高,但是用戶定制程度不高,只能稍微改改表單樣式,AcceptJs可以使用自己設(shè)計(jì)的表單,調(diào)用AcceptJs做安全性校驗(yàn)和數(shù)據(jù)發(fā)送接收。
一. 前期準(zhǔn)備工作 1.1 注冊(cè)一個(gè)沙盒環(huán)境賬號(hào) (必須)沙盒環(huán)境賬號(hào),可以用來(lái)在api文檔頁(yè)面直接調(diào)試各種接口,也可以在沙盒里面查看各種扣款記錄。
如果項(xiàng)目要上線,請(qǐng)注冊(cè)生產(chǎn)環(huán)境賬號(hào),這里全部使用沙盒環(huán)境。
1.2 下載Authorize.net SDK (非必須)下載SDK到項(xiàng)目。
cd /your_php_project_path composer require authorizenet/authorizenet
再在項(xiàng)目中引入即可(如何引入可以看上面地址的介紹,這里不再重復(fù))。
該項(xiàng)目的GITHUB地址:AuthorizeNet/sdk-php 可以在上面搜索、提出你的issues
使用SDK的php案列:AuthorizeNet/sample-code-php
Authorizenet官方實(shí)現(xiàn)的一個(gè)符合PCI標(biāo)準(zhǔn)的案列AuthorizeNet/accept-sample-app (這個(gè)沒(méi)有使用SDK)
1.3 不使用Authorize.net SDK (非必須)因?yàn)锳uthorize.net SDK 要求 php: >=5.5 , 所以只能自己封裝api請(qǐng)求了,具體如何封裝個(gè)人自便,但要說(shuō)明的一點(diǎn)是,Authorize.net 的api,如果選擇的是json格式:
header("Content-type:text/json;charset=utf-8"); $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $this->authorizeUrl); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_COOKIESESSION, true); curl_setopt($curl, CURLOPT_HEADER, 0); curl_setopt($curl, CURLOPT_POST, 1); curl_setopt($curl, CURLOPT_POSTFIELDS, urldecode($data)); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); // curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-Type: text/plain")); //xml request curl_setopt($curl, CURLOPT_HTTPHEADER, array("Accept: application/json")); $result = curl_exec($curl); $curlErrno = curl_errno($curl); $curlError = curl_error($curl); curl_close($curl);
返回的數(shù)據(jù)也是JSON格式,but。。。。,這個(gè)返回的json數(shù)據(jù),是無(wú)法用
json_decode($result,true)
來(lái)解析的,需要
json_decode(substr($result, 3), true);
來(lái)解析。究其原因,應(yīng)該是它返回的數(shù)據(jù)帶了BOM頭,詳細(xì)請(qǐng)移步 json-decode-returns-null
XML格式我沒(méi)有去寫代碼測(cè)試,各位有興趣可以自行測(cè)試,也可以在沙盒環(huán)境直接測(cè)試。
有個(gè)直接扣款的API,其中的ORDER參數(shù)要有順序,要有順序,要有順序,如果遇到一些API,調(diào)試一直報(bào)錯(cuò),但又沒(méi)有特別的原因,請(qǐng)注意看是否是順序問(wèn)題。
1.4 各種環(huán)境地址內(nèi)容 | 測(cè)試環(huán)境 | 生產(chǎn)環(huán)境 |
---|---|---|
api請(qǐng)求地址 | apitest url | api url |
Accept.js | Accept jstest url | Accept js url |
請(qǐng)求支付表單 | test payment/payment | accept payment/payment |
Manage Profiles | Manage Profiles | Manage Profiles |
Add Payment Profile | Add Payment Profile | Add Payment Profile |
Add Shipping Profile | Add Shipping Profile | Add Shipping Profile |
Edit Payment Profile | Edit Payment Profile | Edit Payment Profile |
Edit Shipping Profile | Edit Shipping Profile | Edit Shipping Profile |
需要請(qǐng)求的API : createCustomerProfileRequest
API的詳細(xì)文檔地址:createCustomerProfileRequest
CustomerProfile詳細(xì)介紹:customer_profiles
該API可以在創(chuàng)建CustomerProfileId 的同時(shí),也創(chuàng)建PaymentProfileId 。但是PaymentProfileId需要的參數(shù)都是涉及到用戶敏感信息的,按照PCI標(biāo)準(zhǔn),是不允許商戶收集,所以需要使用Authorize.net的托管表單來(lái)創(chuàng)建。
所以這一步只簡(jiǎn)單的傳遞幾個(gè)參數(shù)即可,使用SDK創(chuàng)建代碼:
$customerProfile = new AnetAPICustomerProfileType(); $customerProfile->setDescription("Customer 2 Test PHP"); $customerProfile->setMerchantCustomerId("11211"); $customerProfile->setEmail($post["email"]); $request = new AnetAPICreateCustomerProfileRequest(); $request->setMerchantAuthentication($this->merchantAuthentication); $request->setProfile($customerProfile); $controller = new AnetControllerCreateCustomerProfileController($request); $response = $controller->executeWithApiResponse( etauthorizeapiconstantsANetEnvironment::SANDBOX);1.2 為添加PaymentInfo托管表單申請(qǐng)token
需要請(qǐng)求的API : getHostedProfilePageRequest
API的詳細(xì)文檔地址:getHostedProfilePageRequest
用上一步創(chuàng)建的CustomerProfileId $profileId = $response->getCustomerProfileId(); 來(lái)獲取token
$setting = new AnetAPISettingType(); $setting->setSettingName("hostedProfileIFrameCommunicatorUrl"); $url = Yii::$app->urlManager->createAbsoluteUrl(["authorizenet/special"]); $setting->setSettingValue($url); $request = new AnetAPIGetHostedProfilePageRequest(); $request->setMerchantAuthentication($this->merchantAuthentication); $request->setCustomerProfileId($profileId); $request->addToHostedProfileSettings($setting); $controller = new AnetControllerGetHostedProfilePageController($request); $response = $controller->executeWithApiResponse( etauthorizeapiconstantsANetEnvironment::SANDBOX);1.3 視圖頁(yè)面iframe使用token加載托管表單
此時(shí)該iframe里面還沒(méi)有任何東西,需要提交這個(gè)form表單才能加載托管表單,這里給一個(gè)函數(shù)讓他頁(yè)面加載的時(shí)候自動(dòng)提交以加載托管表單。
var button = document.getElementById("submit"); button.click();1.4 捕獲響應(yīng)并處理
我們回到 1.2 申請(qǐng)表單這里,這個(gè)API支持設(shè)置托管表單的很多屬性,比較有用的有 :
hostedProfileReturnUrl : 設(shè)置托管會(huì)話結(jié)束(用戶點(diǎn)擊SAVE)返回給用戶的頁(yè)面 (這里省略)
hostedProfileIFrameCommunicatorUrl : 用來(lái)接受、處理Authorize.net響應(yīng)的頁(yè)面
上面設(shè)置的hostedProfileIFrameCommunicatorUrl的頁(yè)面為authorizenet/special
function callParentFunction(str) { var referrer = document.referrer; var s = {qstr : str , parent : referrer}; if(referrer == "https://test.authorize.net/customer/addPayment"){ switch(str){ case "action=successfulSave" : window.parent.parent.location.; break; } } } function receiveMessage(event) { if (event && event.data) { callParentFunction(event.data); } } if (window.addEventListener) { window.addEventListener("message", receiveMessage, false); } else if (window.attachEvent) { window.attachEvent("onmessage", receiveMessage); } if (window.location.hash && window.location.hash.length > 1) { callParentFunction(window.location.hash.substring(1)); }
這里設(shè)置成功保存paymentInfo 信息到Authorize.net之后就跳轉(zhuǎn)到 payment 頁(yè)面支付。
action有不同的狀態(tài),可以根據(jù)action作相應(yīng)的處理。
resizeWindow : 托管表單加載
successfulSave : 表單成功保存(CustomerProfile)
cancel : 用戶點(diǎn)擊取消按鈕
transactResponse :支付成功(payment)
需要請(qǐng)求的API : getCustomerProfileRequest
API的詳細(xì)文檔地址:getCustomerProfileRequest
$customer = $this->getCustomerProfile($profileId); $billTo = end($customer->getProfile()->getPaymentProfiles())->getBillTo();
因?yàn)橐粋€(gè)CustomerProfi對(duì)應(yīng)多個(gè)PaymentProfile ,這里獲取最后一個(gè)PaymentProfile。
1.2 為添加Payment托管表單申請(qǐng)token需要請(qǐng)求的API : getHostedPaymentPageRequest
API的詳細(xì)文檔地址:getHostedPaymentPageRequest
請(qǐng)求該URL,可以指定加載表單的樣式等各種參數(shù),具體參考:Accept Hosted feature details page
$transactionRequestType = new AnetAPITransactionRequestType(); $transactionRequestType->setTransactionType("authCaptureTransaction"); $transactionRequestType->setAmount("12.23"); $customer = $this->getCustomerProfile(Yii::$app->session->get("profileId")); $billTo = end($customer->getProfile()->getPaymentProfiles())->getBillTo(); $transactionRequestType->setBillTo($billTo);//回填賬單地址 $customer = new AnetAPICustomerDataType(); $customer->setEmail(Yii::$app->session->get("email")); $customer->setId(Yii::$app->session->get("user_id")); $transactionRequestType->setCustomer($customer); $request = new AnetAPIGetHostedPaymentPageRequest(); $request->setMerchantAuthentication($this->merchantAuthentication); $request->setTransactionRequest($transactionRequestType); $setting3 = new AnetAPISettingType(); $setting3->setSettingName("hostedPaymentReturnOptions"); $setting3->setSettingValue("{"url": "https://www.basic.com/index.php?r=authorizenet/receipt", "cancelUrl": "https://www.basic.com/index.php?r=authorizenet/cancel", "showReceipt": false}"); $request->addToHostedPaymentSettings($setting3); //設(shè)置托管表單顯示email,且必填 (因?yàn)閒orm表單沒(méi)有禁止修改email參數(shù),所以可以設(shè)置email但不顯示在表單中,以防修改) $setting4 = new AnetAPISettingType(); $setting4->setSettingName("hostedPaymentCustomerOptions"); $setting4->setSettingValue("{"showEmail": true, "requiredEmail":true}"); $request->addToHostedPaymentSettings($setting4); $setting6 = new AnetAPISettingType(); $setting6->setSettingName("hostedPaymentIFrameCommunicatorUrl"); $url = Yii::$app->urlManager->createAbsoluteUrl(["authorizenet/special"]); $setting6->setSettingValue("{"url": "".$url.""}"); $request->addToHostedPaymentSettings($setting6); $controller = new AnetControllerGetHostedPaymentPageController($request); $response = $controller->executeWithApiResponse( etauthorizeapiconstantsANetEnvironment::SANDBOX); if (($response != null) && ($response->getMessages()->getResultCode() == "Ok") ) { return $response->getToken(); }1.3 視圖頁(yè)面iframe使用token加載托管表單
1.4 捕獲響應(yīng)并處理。
同 二.1.14 一致,可以設(shè)置為同一個(gè)頁(yè)面,通過(guò)referrer來(lái)判斷是完善支付信息表單的響應(yīng),還是支付表單的響應(yīng)
如:
if(referrer == "https://test.authorize.net/customer/addPayment"){ //your code }else if(referrer == "https://test.authorize.net/payment/payment"){ //your code }else if(other){ //your code }3. 最終效果圖
(支付完成后的處理我沒(méi)做,無(wú)非就是彈個(gè)窗之類的告訴用戶支付成功,再處理后臺(tái)邏輯之類的)
可以看到,這里只可以回填賬單地址、客戶電話和email之類的信息。信用卡、信用卡過(guò)期時(shí)間、信用卡安全碼等都無(wú)法回填,需要用戶再次輸入,用戶體驗(yàn)非常不好。
所以支付這一步我們可以不用托管表單,使用通過(guò)CustomerProfileID發(fā)起支付的API來(lái)完成
需要請(qǐng)求的API : createTransactionRequest
API的詳細(xì)文檔地址:createTransactionRequest
$paymentprofileid = $this->getCustomerProfile($profileid); $profileToCharge = new AnetAPICustomerProfilePaymentType(); $profileToCharge->setCustomerProfileId($profileid); $paymentProfile = new AnetAPIPaymentProfileType(); $paymentProfile->setPaymentProfileId($paymentprofileid); $profileToCharge->setPaymentProfile($paymentProfile); $transactionRequestType = new AnetAPITransactionRequestType(); $transactionRequestType->setTransactionType( "authCaptureTransaction"); $transactionRequestType->setAmount(5); $transactionRequestType->setProfile($profileToCharge); $request = new AnetAPICreateTransactionRequest(); $request->setMerchantAuthentication($this->merchantAuthentication); $request->setTransactionRequest( $transactionRequestType); $controller = new AnetControllerCreateTransactionController($request); $response = $controller->executeWithApiResponse( etauthorizeapiconstantsANetEnvironment::SANDBOX);4. 結(jié)尾補(bǔ)充
托管表單要求你的程序掛載在HTTPS域名下
還可以通過(guò)CustomerProfileId、paymentProfileId發(fā)起ARB(Auto Recurring Billing)扣款
需要請(qǐng)求的API : ARBCreateSubscriptionRequest
API的詳細(xì)文檔地址:getHostedPaymentPageRequest
關(guān)于APB的詳細(xì)介紹請(qǐng)看:recurring_billing
關(guān)于測(cè)試請(qǐng)看:testing_guide
可以填寫不同的 Zip Code 和 Card Code 來(lái)模擬不同的錯(cuò)誤返回
(缺)1. 加載AccpectJS
(缺)2. 巴拉巴拉
(缺)
缺失的內(nèi)容請(qǐng)自行參考官方demo。。。。。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/25624.html
摘要:前言之前的一個(gè)人安全部的大師傅把我們拉在了一起,然后逐漸發(fā)現(xiàn)群里大師傅們也發(fā)了建設(shè)經(jīng)驗(yàn)文章。月入職,一家具有支付牌照的互聯(lián)網(wǎng)金融公司,網(wǎng)絡(luò)運(yùn)維部下。 前言 之前的一個(gè)人安全部的77大師傅把我們拉在了一起,然后逐漸發(fā)現(xiàn)群里大師傅們也發(fā)了建設(shè)經(jīng)驗(yàn)文章。好吧,這么懶得我也分享下自己的經(jīng)驗(yàn),也就當(dāng)對(duì)這2年多來(lái)的甲方經(jīng)驗(yàn)的總結(jié)。感謝群里的小伙伴們,感謝安全圈的各路大牛們和小伙伴們的幫助,更感謝朝...
摘要:本部分是可以找到有關(guān)功能和概念的大部分信息的地方。促銷系統(tǒng)包含一個(gè)高度可配置的促銷系統(tǒng)。異步消息通過(guò)與現(xiàn)代代理交互,實(shí)現(xiàn)應(yīng)用程序消息的異步處理。將智能地將自己的配置信息與實(shí)施者在運(yùn)行時(shí)提供的信息合并。添加了方法以允許包含任何符合的加密方案。 本部分是可以找到有關(guān)Broadleaf功能和概念的大部分信息的地方。我們描述了購(gòu)物車修改,定價(jià)和付款等操作的重要性,以及Broadleaf支持的其...
摘要:而適配器其實(shí)在中應(yīng)該是比較常見的一種了。在維基百科中,關(guān)于適配器模式的定義為在軟件工程中,適配器模式是一種軟件設(shè)計(jì)模式,允許從另一個(gè)接口使用現(xiàn)有類的接口。 適配器設(shè)計(jì)模式在JavaScript中非常有用,在處理跨瀏覽器兼容問(wèn)題、整合多個(gè)第三方SDK的調(diào)用,都可以看到它的身影。 其實(shí)在日常開發(fā)中,很多時(shí)候會(huì)不經(jīng)意間寫出符合某種設(shè)計(jì)模式的代碼,畢竟設(shè)計(jì)模式就是老前輩們總結(jié)提煉出來(lái)的一些能...
摘要:月,在谷歌云平臺(tái)會(huì)議上,我們?cè)陔娮又Ц短峁┥痰膶?shí)踐中看到了成功。打破了單個(gè)程序到一套通過(guò)谷歌開源平臺(tái)容器編排引擎來(lái)合作的模式。這周,谷歌發(fā)布了的最新版本,版本是一個(gè)企業(yè)友好型平臺(tái),比如說(shuō)它支持有狀態(tài)應(yīng)用程序。 我們聽說(shuō)了很多關(guān)于容器編排執(zhí)行得好,就能夠流水化 IT 和業(yè)務(wù)流程的信息。3 月,在谷歌云平臺(tái)會(huì)議上,我們?cè)陔娮又Ц短峁┥?WePay 的實(shí)踐中看到了成功。WePay 打破了單個(gè)...
摘要:更不用說(shuō)云計(jì)算服務(wù)提供商可能會(huì)免除服務(wù)水平協(xié)議中的任何責(zé)任。數(shù)據(jù)安全和員工大多數(shù)與員工相關(guān)的事件并不是惡意的。云計(jì)算服務(wù)提供商并不會(huì)為客戶承擔(dān)不必要的責(zé)任。越來(lái)越多的企業(yè)將業(yè)務(wù)遷移到云計(jì)算平臺(tái),這意味著其對(duì)數(shù)據(jù)安全的責(zé)任顯著增加。具有各種敏感度的數(shù)據(jù)正在超出企業(yè)防火墻的范圍。企業(yè)將不再擁有控制權(quán),其數(shù)據(jù)可能位于世界任何地方,并可能取決于其合作的云計(jì)算供應(yīng)商。企業(yè)將業(yè)務(wù)遷移到公共云或使用混合云...
閱讀 3460·2023-04-26 01:46
閱讀 3026·2023-04-25 20:55
閱讀 5625·2021-09-22 14:57
閱讀 3032·2021-08-27 16:23
閱讀 1772·2019-08-30 14:02
閱讀 2126·2019-08-26 13:44
閱讀 701·2019-08-26 12:08
閱讀 3180·2019-08-26 11:47