前言
因为业务的需要,公司的游戏不断的向海外拓展.自然地,我们的游戏也要根据当地的需要接入不同的支付方式.其中,最具代表性的,首当其冲的非苹果支付和谷歌支付莫属.但是,除此之外也有其他的支付方式,比如PayPal,Mycard等等.
PayPal支付
相对于国外其他的第三方支付,Paypal支付算是一个比较容易上手的第三方支付.Paypal支付移动SDK继承三种方式的支付,如下所示:
- a) 接受信用卡和Paypal支付: 开发者能够简单地将Paypal支付和信用卡支付集成到应用中,信用卡支付手动支付和扫码支付.
- b) 未来支付: 一旦客户将Paypal账户授权给开发者的应用中,使用Paypal支付时无需再次登录即可完成付款.
- c) 原生支付: 用户付款时无需重定向到新页面即可完成付款
OAuth2协议
- 1)开发者使用key和secret向Paypal服务器请求token(OAuth2协议).
- 2)之后的请求都需要携带token认证完成操作.
- 3)用户支付成功之后,服务端需要将利用客户端回传的数据向Paypal发起支付确认.
- 4)当token过期失效是重新获取Token.
获取授权Token
开发者从开发者后台相应的应用上获取client_id和secret.通过这两个秘钥串想服务器请求token.
1 2 3 4 5
| curl -v https://api.sandbox.paypal.com/v1/oauth2/token \ -H "Accept: application/json" \ -H "Accept-Language: en_US" \ -u "client_id:secret" \ -d "grant_type=client_credentials"
|
请求成功之后,响应的参数格式数如下所示:
其中, Access-Token 表示获取到token值.expires_in表示该token的过期时间.scope表示授权可请求的权限.
1 2 3 4 5 6 7 8
| { "scope": "https://uri.paypal.com/services/subscriptions https://api.paypal.com/v1/payments/.* https://api.paypal.com/v1/vault/credit-card https://uri.paypal.com/services/applications/webhooks openid https://uri.paypal.com/payments/payouts https://api.paypal.com/v1/vault/credit-card/.*", "nonce": "2017-06-08T18:30:28ZCl54Q_OlDqP6-4D03sDT8wRiHjKrYlb5EH7Di0gRrds", "Access-Token": "Access-Token", "token_type": "Bearer", "app_id": "APP-80W284485P519543T", "expires_in": 32398 }
|
支付验证
开发者通过将结合用户支付成功之后从客户端回传的参数(订单号)向Paypal服务器指定的API请求支付验证.此时需要在请求头中携带token.
1 2 3
| curl https://api.sandbox.paypal.com/v1/payments/payment/PAY-5YK922393D847794YKER7MUI \ -H "Content-Type: application/json" \ -H "Authorization: Bearer accessToken"
|
请求成功之后,响应的参数格式如下所示:
其中,environment表示请求的支付环境,分为sandbox(沙盒模式)和正式模式(live).state表示支付状态,approved表示支付验证已通过. 开发者可以通过对响应值携带的相关参数进行二次验证.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| { "client":{ "environment":"sandbox", "paypal_sdk_version":"2.0.0", "platform":"iOS", "product_name":"PayPal iOS SDK;" }, "response":{ "create_time":"2014-02-12T22:29:49Z", "id":"PAY-564191241M8701234KL57LXI", "intent":"sale", "state":"approved" }, "response_type":"payment" }
|
Mycard支付
Mycard支付是一个主要面向港澳台地区游戏充值代币平台,它的主要优势在于能够因地适宜的提供适合当地支付方式.按照交易模式来划分,主要分为网页支付和客户端支付两种.而按照付费方式来划分,又可以分为卡片支付、会员扣点交易、小额付款交易.
申请交易授权码
研发商在进行所有的相关的交易之前,需要向Mycard服务端申请授权码.当交易模式为Web,付费方式为INGAME,充值服务为Server-side时,此时进入网页版本支付模式.否则就是客户端支付.
客户端支付
支付流程
- 客户端通过API向服务端发起请求,由服务端代客户端向Mycard服务端申请相关的授权码.服务端相关的代码如下所示.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| function getMyCardAuthCode($arrData){ $arrGetMyCardAuthWhere = array( "FacServiceId" => $this->arrConfigSDK['FacServiceId'], "FacTradeSeq" => $arrData['FacTradeSeq'], "TradeType" => $this->arrConfigSDK['TradeType'], "ServerId" => $arrData['ServerId'], "CustomerId" => $arrData['CustomerId'], "PaymentType" => "", "ItemCode" => "", "ProductName" => strtolower(urlencode($arrData['ProductName'])), "Amount" => $arrData['Amount'], "Currency" => strtoupper($arrData['Currency']), "SandBoxMode" => $this->arrConfigSDK['sandBox'], ); $signature = $this->getPaySign($arrGetMyCardAuthWhere); $arrGetMyCardAuthWhere['Hash'] = $signature; $rootUrlMyCard= $this->arrConfigSDK['sandBox'] ? self::urlMyCardAuthTest : self::urlMyCardAuthB2B; $urlMyCard = $rootUrlMyCard."?".urldecode(http_build_query($arrGetMyCardAuthWhere,NULL,"&")); $arrGetMyCardAuth = $this->paySDK->curlPayByGet($urlMyCard); $this->logRequest($urlMyCard.PHP_EOL.$arrGetMyCardAuth); return empty($arrGetMyCardAuth) ? array() : json_decode($arrGetMyCardAuth,true); }
|
- 客户端获取相应的授权码之后,在SDK内发起支付请求唤起支付界面,再由玩家进行支付操作.
- 当玩家在游戏内成功完成交易之后,将申请得到的授权码再回传给我服务端请求发货.
- 服务端获取到授权码之后先去验证交易结果,然后再进行请款,最后在请求发货.
1 2 3 4 5 6 7 8 9 10 11 12 13
| function getMyCardTradeQuery($arrData){ if(!empty($arrData['AuthCode'])){ $arrAuthCode = array( "AuthCode" => $arrData['AuthCode'] ); $rootUrlMyCard = $this->arrConfigSDK['sandBox'] ? self::urlMyCardQueryTest : self::urlMyCardQueryB2B; $urlMyCard = $rootUrlMyCard."?".http_build_query($arrAuthCode,NULL,"&"); $arrGetMyCard = $this->paySDK->curlPayByGet($urlMyCard); $this->logRequest($urlMyCard.PHP_EOL.$arrGetMyCard); $arrRst = empty($arrGetMyCard) ? array() : json_decode($arrGetMyCard,true); } return empty($arrRst) ? array() : $arrRst; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| function getMyCardPaymentConfirm($arrData){ if(!empty($arrData['AuthCode'])){ $arrAuthCode = array( "AuthCode" => $arrData['AuthCode'] ); $rootUrlMyCard = $this->arrConfigSDK['sandBox'] ? self::urlMyCardConfirmTest : self::urlMyCardConfirmB2B; $urlMyCard = $rootUrlMyCard."?".http_build_query($arrAuthCode,NULL,"&"); $arrGetMyCard = $this->paySDK->curlPayByGet($urlMyCard); $this->logRequest($urlMyCard.PHP_EOL.$arrGetMyCard); $arrRst = empty($arrGetMyCard) ? array() : json_decode($arrGetMyCard,true); } return empty($arrRst) ? array() : $arrRst; }
|
网页版支付
进入网页版支付模式下,网页支付可分为自定义页面以及官方推荐页面.
支付流程
- 玩家选择指定的充值档位之后需要通过Ajax向服务端发起请求,由服务端代网页端向Mycard服务端申请相关的授权码.服务端相关的代码略.
- 玩家需要填写支付的点卡信息,网页需要将授权码和相关的点卡信息给服务端先进行验证,再进行请款,最后再请求发货.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| function getMyCardPayInGamePay($arrData){ if(!empty($arrData['AuthCode']) && !empty($arrData['CardID']) && !empty($arrData['CardPW'])){ $arrMyCardInGamePayWhere = array( "AuthCode" => $arrData['AuthCode'], "CardID" => $arrData['CardID'], "CardPW" => $arrData['CardPW'], ); $signature = $this->getPaySign($arrMyCardInGamePayWhere); $arrMyCardInGamePayWhere['Hash'] = $signature; $rootUrlMyCard = $this->arrConfigSDK['sandBox'] ? self::urlMyCardInGamePayTest : self::urlMyCardInGamePayB2B; $urlMyCard = $rootUrlMyCard."?".http_build_query($arrMyCardInGamePayWhere,NULL,"&"); $arrGetMyCard = $this->paySDK->curlPayByGet($urlMyCard); $this->logRequest($urlMyCard.PHP_EOL.$arrGetMyCard); $arrRst = empty($arrGetMyCard) ? array() : json_decode($arrGetMyCard,true); } return empty($arrRst) ? array() : $arrRst; }
|
思考
参考资料