网游支付服务
目录
1.流程介绍
1. 应用调用应用服务器进行下单;
2. 应用调用360SDK支付接口;
3. 360SDK展示支付页面,引导用户完成支付流程;
a. 若调用接口时指定金额,则显示固定金额支付界面;
b. 若调用接口时不指定金额,则显示不固定金额的支付界面;
4. 支付结束或退出360SDK支付客户端界面后,360SDK客户端会返回支付结果给应用客户端的支付模块;
5. 支付成功后,360服务器回调应用服务器上的通知接口,通知支付结果;
6. (可选) 应用服务器调用360服务器端订单确认接口,验证支付通知的合法性;
2.接口介绍
2.1支付接口【客户端调用】(必接)
功能说明:
应用调用360SDK支付接口时,360SDK弹出支付选择界面。用户在界面上完成支付。
关于应用方订单号的问题:应用方需要生成自己的订单号app_order_id,应用订单号不能重复提交,并且一个应用订单不管是否支付成功,都只能支付一次。这样做是为了避免重复支付。通知应用方加钱时,会返回应用订单号, 同时提供360订单号。
Access token由于与当前登录用户id绑定,因此可以加强支付安全性。但要注意token的时间期限(有效期为10小时)。过期后调用支付接口会失败。游戏可以引导用户重新登录.
接口示例:
注意:
1、 必选参数不能为空, 不能为0,否则支付失败。
2、参数名,以ProtocolKeys中定义的常量为准。
/** * 使用360SDK的支付接口 * * @param isLandScape 是否横屏显示支付界面 * @param isFixed 是否定额支付 */ protected void doSdkPay(final boolean isLandScape, final boolean isFixed) { if(!isAccessTokenValid) { Toast.makeText(SdkUserBaseActivity.this, R.string.access_token_invalid, Toast.LENGTH_SHORT).show(); return; } if(!isQTValid) { Toast.makeText(SdkUserBaseActivity.this, R.string.qt_invalid, Toast.LENGTH_SHORT).show(); return; } // 支付基础参数 Intent intent = getPayIntent(isLandScape, isFixed); // 必需参数,使用360SDK的支付模块。 intent.putExtra(ProtocolKeys.FUNCTION_CODE, ProtocolConfigs.FUNC_CODE_PAY); // 可选参数,登录界面的背景图片路径,必须是本地图片路径 intent.putExtra(ProtocolKeys.UI_BACKGROUND_PICTRUE, ""); Matrix.invokeActivity(this, intent, mPayCallback); } /** * 生成调用360SDK支付接口基础参数的Intent * * @param isLandScape 是否横屏显示登录界面 * @param isFixed 是否定额支付 * * @return Intent */ protected Intent getPayIntent(boolean isLandScape, boolean isFixed) { Bundle bundle = new Bundle(); QihooPayInfo pay = getQihooPayInfo(isFixed); // 界面相关参数,360SDK界面是否以横屏显示。 bundle.putBoolean(ProtocolKeys.IS_SCREEN_ORIENTATION_LANDSCAPE, isLandScape); // 可选参数,登录界面的背景图片路径,必须是本地图片路径 bundle.putString(ProtocolKeys.UI_BACKGROUND_PICTRUE, ""); // *** 以下非界面相关参数 *** // 设置QihooPay中的参数。 // 必需参数,用户access token,要使用注意过期和刷新问题,最大64字符。 bundle.putString(ProtocolKeys.ACCESS_TOKEN, pay.getAccessToken()); // 必需参数,360账号id。 bundle.putString(ProtocolKeys.QIHOO_USER_ID, pay.getQihooUserId()); // 必需参数,所购买商品金额, 以分为单位。金额大于等于100分,360SDK运行定额支付流程; 金额数为0,360SDK运行不定 额支付流程。 bundle.putString(ProtocolKeys.AMOUNT, pay.getMoneyAmount()); // 必需参数,人民币与游戏充值币的默认比例,例如2,代表1元人民币可以兑换2个游戏币,整数。 bundle.putString(ProtocolKeys.RATE, pay.getExchangeRate()); // 必需参数,所购买商品名称,应用指定,建议中文,最大10个中文字。 bundle.putString(ProtocolKeys.PRODUCT_NAME, pay.getProductName()); // 必需参数,购买商品的商品id,应用指定,最大16字符。 bundle.putString(ProtocolKeys.PRODUCT_ID, pay.getProductId()); // 必需参数,应用方提供的支付结果通知uri,最大255字符。360服务器将把支付接口回调给该uri,具体协议请查看文档中, 支付结果通知接口–应用服务器提供接口。 bundle.putString(ProtocolKeys.NOTIFY_URI, pay.getNotifyUri()); // 必需参数,游戏或应用名称,最大16中文字。 bundle.putString(ProtocolKeys.APP_NAME, pay.getAppName()); // 必需参数,应用内的用户名,如游戏角色名。 若应用内绑定360账号和应用账号,则可用360用户名,最大16中文字。(充 值不分区服,充到统一的用户账户,各区服角色均可使用)。 bundle.putString(ProtocolKeys.APP_USER_NAME, pay.getAppUserName()); // 必需参数,应用内的用户id。 // 若应用内绑定360账号和应用账号,充值不分区服,充到统一的用户账户,各区服角色均可使用,则可用360用户ID最大32 字符。 bundle.putString(ProtocolKeys.APP_USER_ID, pay.getAppUserId()); // 必需参数,应用订单号,应用内必须唯一,最大32字符。 bundle.putString(ProtocolKeys.APP_ORDER_ID, pay.getAppOrderId()); // 可选参数,应用扩展信息1,原样返回,最大255字符。 bundle.putString(ProtocolKeys.APP_EXT_1, pay.getAppExt1()); // 可选参数,应用扩展信息2,原样返回,最大255字符。 bundle.putString(ProtocolKeys.APP_EXT_2, pay.getAppExt2()); Intent intent = new Intent(this, ContainerActivity.class); intent.putExtras(bundle); return intent; }
callback的 json数据格式:
成功返回
{error_code: 0, error_msg: "支付成功", content:""}
失败返回
{error_code: 1, error_msg: "支付失败", content:""}
取消返回
{error_code: -1, error_msg: "支付取消", content:""}
支付正在进行
{error_code: -2, error_msg: "正在进行", content:""}
access_token失效
{error_code: 4010201, error_msg: " token已失效", content:""}
QT失效
{error_code: 4009911, error_msg: " 登录已失效", content:""}
callback示例:
2.2支付结果通知接口–应用服务器提供接口, 由360服务器回调(必接)
应用客户端调用支付接口时, 需指定支付结果的通知回调地址notify_uri. 支付完成后, 360服务器会把支付结果以GET方式通知到此地址 (建议应用服务端接口同时支持GET和POST). 应用接收验证参数后, 给用户做游戏内充值.
应用服务端通知接口在接收到通知消息后, 需回应ok(仅返回小写ok这两个字母,不要有其它输出), 表示通知已经接收. 如果回应其他值或者不回应, 则被认为通知失败, 360会尝试多次通知. 这个机制用来避免掉单。
应用应做好接收到多次通知的准备, 防止多次加钱. 同时, 需要特别注意的是, 回应的ok表示应用已经正常接到消息, 无需继续发送通知. 它不表示订单成功与否, 或者应用处理成功与否. 对于重复的通知, 应用可能发现订单已经成功处理完毕, 无需继续处理, 也要返回ok(仅返回小写ok这两个字母,不要有其它输出). 否则, 360会认为未成功通知, 会继续发送通知.
支付结果通知的参数如下:
参数 |
必选 |
参数类型 |
最大长度 |
参数说明 |
是否参与签名 |
app_key |
Y |
varchar |
32 |
应用app key |
Y |
product_id |
Y |
varchar |
36 |
应用自定义的商品id |
Y |
amount |
Y |
int unsigned |
11 |
总价,以分为单位 |
Y |
app_uid |
Y |
varchar |
50 |
应用分配给用户的id |
Y |
app_ext1 |
N |
varchar |
255 |
应用扩展信息1原样返回 |
Y |
app_ext2 |
N |
varchar |
255 |
应用扩展信息2原样返回 |
Y |
user_id |
Y |
bigint unsigned |
20 |
360账号id |
Y |
order_id |
Y |
bigint unsigned |
20 |
360返回的支付订单号 |
Y |
gateway_flag |
Y |
varchar |
16 |
如果支付返回成功,返回success 应用需要确认是success才给用户加钱 |
Y |
sign_type |
Y |
varchar |
8 |
定值 md5 |
Y |
app_order_id |
N |
varchar |
64 |
应用订单号 支付请求时传递,原样返回 |
Y |
sign_return |
Y |
varchar |
32 |
应用回传给订单核实接口的参数 不加入签名校验计算 |
N |
sign |
Y |
varchar |
32 |
签名 |
N |
应用接收到支付平台回调的请求,参见附录的签名算法对参数进行签名,然后和平台传递的签名sign比较,从而校验平台请求的合法性.
通知消息样例:
order_id=1211090012345678901&app_key=1234567890abcdefghijklmnopqrstuv&product_id=p1&amount=101&app_uid=123456789& app_ext1=XXX201211091985&app_order_id=order1234&user_id=987654321&sign_type=md5&gateway_flag=success&sign=xxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxx&sign_return=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
样例的签名字段排列 (列出来仅供参考, 请根据实际参数情况用程序排序产生, 不要写死在程序里)
amount, app_ext1, app_key, app_order_id, app_uid, gateway_flag, order_id, product_id, sign_type, user_id
样例的签名串
101#XXX201211091985#1234567890abcdefghijklmnopqrstuv#order1234#123456789#success#1211090012345678901#p1#md5#987654 321#应用app_secret
2.3订单核实接口– 服务器端接口, 应用服务器调用(可选)
1. 验证接口地址为: http://mgame.360.cn/pay/order_verify.json
2. 为了安全起见,验证参数不需要传client_id,client_secret参数,如果传了服务端会报错
3. 需要计算签名
为了防止伪造的支付成功通知, 应用可以使用本接口做通知数据的校验.把支付结果通知接口(4.2.2节)收到的通知消息里的参数, 计算签名后调用接口, 即可校验数据是否正确.
接口地址:
http://mgame.360.cn/pay/order_verify.json?参数
参数说明:
参数 |
必选 | 参数说明 |
app_key | Y | 应用 app key |
product_id | Y | 应用自定义的商品 id |
amount | Y | 总价,单位:分 |
app_uid | Y | 应用分配给用户的 id |
order_id | Y | 360 支付订单号 |
app_order_id | N | 应用订单号 下单时若指定验证时也要指定 |
app_ext1 |
N | 应用扩展信息 1 |
app_ext2 | N | 应用扩展信息 2 |
is_sms |
N | 是否短信支付 |
bank_code |
N | 支付方式 |
pay_ext |
N | 扩展信息 |
sign_type |
Y | 当前仅支持 md5 |
sign_return |
Y | 应用传给订单核实接口的参数 sign_return |
sign |
Y | 签名(计算方法参考附录 6.1 节,本表格中除 sign 以外的所有参数均参与签名) |
参数均来自应用加钱接口收到的支付通知消息, 原样提供即可。
如果参数提供正确, 订单核实接口返回为json格式数据.
验证成功返回
{"ret":"verified"}
验证不成功返回
{"ret":"{错误信息}"}
返回结果中可能的错误信息包括
错误信息 |
错误说明 |
order not exists |
订单不存在 |
product_id not match |
订单验证传入的 product_id 和下单时传入的 product_id 不一致 |
amount not match |
验证金额与下单时金额不一致 |
user_id not match |
验证 360 用户 id 和下单时 360 用户 id 不一致 |
bank_code not match |
验证支付方式和下单时支付方式不一致 |