xsolla支付
xsolla支付
xsolla: 您已尽心尽力开发出令人惊叹、独一无二的游戏。作为您的合作伙伴,帮助您将成果与世界共享是我们的使命。
作为开发者在集成xsolla支付接口之前,首先要有一系列的准备,xsolla商家账号,接入流程参考官方文档 https://developers.xsolla.com/zh/doc/pay-station/integration-guide/get-started/
1. 注册xsolla商家账号
- 在浏览器输入 https://publisher.xsolla.com/跳转xsolla注册/登陆界面,点击注册
- 填写公司和创建项目,用于生成商户id
注意
自己在这里遇到一个坑,在创建账号时创建的项目不是active的我也不清楚为啥,导致后面的请求都不行,后来联系了平台人员,我把项目删了重新新建一个,刚建完就是active的,就很奇妙
官方的人员很热情,回复得也很快很有耐心,直接点击下面的在线聊天就能沟通,点赞,下面是部分回复
相关信息
我:你好,我是开发人员,我想接入咱们的支付功能,在获取用户令牌时返回
"message": "Project is not active. Please make sure you have successfully passed all tests
<a href=\"https:\/\/publisher.xsolla.com\/403694\/projects\/217604\" target=\"_blank\">here<\/a> and activate your project.",
这是因为什么?
Simon:
https://publisher.xsolla.com/403694/projects/217604/edit/webhooks您还需要设置 webhook 并粘贴 webhook 的 URL 以激活您的项目。
我:我是按照咱们官方文档步骤来的,webhook这一块下面的商店/支付/订阅都需要填写才能激活项目吗?
Simon
https://developers.xsolla.com/solutions/payments/ 它是付款文档,但您可以在那里看到有关如何设置项目和启用它的所有信息。它还有关于 webhook 的主题。
我:按照上面操作了一顿还是不行,后来干脆把创建账号时创建的项目删了,再按照上面创建一个,直接变成active的了,很奇妙
Simon: 很高兴分享指向我们最相关解决方案的链接。 您还可以使用我发送给您的链接来集成它并启用您的项目。
您还可以查看最适合您的项目的内容。
支付 - https://xsolla.com/products/paystation
游戏内商店 - https://xsolla.com/products/in-game-store
网上商店 - https://xsolla.com/solution/web-shop-for-mobile-games?cardId=290
游戏销售 - https://xsolla.com/solutions/online-game-sales?cardId=166
数字分销中心 - https://xsolla.com/products/digital-distribution-hub
订阅 - https://xsolla.com/products/subscriptions
Simon:
您可以在发布者帐户中选择产品,单击感兴趣的产品选项卡中的文档。还有一个完整的集成指南,其中包括启用您的项目和产品
1.1 商户ID:
- 在 项目设置 > Webhooks 部分。 记录商户id,项目id,api密钥备用(webhook)
- 在 公司设置 > 公司 部分。
1.2 API密钥
仅在创建它时在发布商帐户中显示一次,必须存储在己侧。可以在以下部分中创建新的密钥:
- 公司设置 > API密钥
- 项目设置 > API密钥
2. 获取用户令牌
封装请求头信息
xsollaAPI使用基本认证 。所有发送到API的请求必须包含 Authorization: Basic <your_authorization_basic_key> 头,其中 <your_authorization_basic_key> 是按照Base64标准加密的 商户ID: API密钥 对。请前往 发布商帐户 找到以下参数:
//授权信息
String xsollaUserId = constantInfo.getUserId();//商户id
String appId = constantInfo.getAppId();//项目id
String appKey = constantInfo.getAppKey();//密钥
String headerBasic = OauthSignatureUtil.headerBasic(xsollaUserId, appKey);//方法参见java-paypal
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", headerBasic);
对于请求提没什么可说的直接按照文档上赋值就可以了
示例代码:
@Override
@OperationLogger
public ReturnResult createToken(CreateTokenParams params) {
String userId = params.getUserId();
String gameId = params.getGameId();
String channelId = params.getChannelId();
String email = params.getEmail();
String currencyType = params.getCurrencyType();
//验证账号是否存在
UserAccountInfo accountInfo = UserAccountInfo.builder().userId(userId).build();
accountInfo = userAccountInfoMapper.selectOne(new QueryWrapper<>(accountInfo));
if (accountInfo == null) {
return ReturnResultError.builder().code(ConstantCommon.RETURN_CODE_903).msg("账号不存在").data("")
.build();
}
String username = accountInfo.getUsername();
//查询渠道配置信息
ConstantMeInfo constantInfo = getCacheConstantInfo(gameId, channelId, "xsolla");
//授权信息
String xsollaUserId = constantInfo.getUserId();//商户id
String appId = constantInfo.getAppId();//项目id
String appKey = constantInfo.getAppKey();//密钥
String headerBasic = OauthSignatureUtil.headerBasic(xsollaUserId, appKey);//方法参见java-paypal
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", headerBasic);
//请求体
Map<String, Object> xsollaParams = new HashMap<>();
xsollaParams.put("settings", new HashMap<String, Object>() {{
put("currency", currencyType);
put("language", "en");//xsolla支付界面语言。可定制化配置
put("project_id", Integer.parseInt(appId));
}});
xsollaParams.put("user", new HashMap<String, Object>() {{
put("email", new HashMap<String, String>() {{
put("value", email);
}});
put("id", new HashMap<String, String>() {{
put("value", userId);
}});
put("name", new HashMap<String, String>() {{
put("value", username);
}});
}});
Map<String, String> createToken = client.postByJsonToMap("https://api.xsolla.com/merchant/v2/merchants/" + xsollaUserId + "/token", headers, xsollaParams);
System.out.println(JSON.toJSONString(createToken));
return ReturnResultSuccess.builder().code(ConstantCommon.RETURN_CODE_200).msg("订单创建成功").data(JSON.toJSONString(createToken))
.count(ConstantCommon.RETURN_COUNT_1).build();
}
这样就拿到了用户的token信息
{
"token":"twpuiVlqxd95a0rL2isA7RmTjSD7rzXa_lc_en_bg_FFFFFF_tb_3D46F5"
}
3. 使用指定商品创建订单
目前使用的是指定商品创建订单,商品信息需要在商户后台提前配置,项目-商店-虚拟商品,配置即可,也可以使用api创建虚拟商品
https://developers.xsolla.com/zh/api/igs-bb/operation/admin-create-virtual-item/

提示
请求地址: https://store.xsolla.com/api/v2/project/{projectId}/payment/item/{productId}
projectId:项目id,productId:商品id,sku
封装请求头信息,用到上步骤获取的用户令牌
//授权信息
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", "Bearer " + token);
封装用户付款ui
//配置ui显示
Map<String, Object> ui = new HashMap<>();
ui.put("desktop", new HashMap<String, Object>() {{//桌面版本的界面设置。
put("header", new HashMap<String, Object>() {{
put("close_button", false);//是否在支付中心桌面端显示关闭按钮。该按钮将关闭支付中心并将用户重定向到settings.return_url参数中指定的URL。默认为false。
put("is_visible", true);//页眉在支付UI上是否可见。
put("type", "normal");//如何显示页眉。不能:compact(隐藏项目名称和用户ID)或normal(默认)
put("visible_logo", true);//标题中将显示Logo
put("visible_name", true);//页眉中是否显示项目名称。
put("visible_purchase", true);//是否在页眉中显示购买描述(purchase.description.value )
}});
}});
ui.put("mobile", new HashMap<String, Object>() {{
put("footer", new HashMap<String, Object>() {{
put("is_visible", true);//是否在移动版本的支付UI中隐藏或显示脚注。
}});
put("header", new HashMap<String, Object>() {{
put("close_button", false);//是否在支付中心移动端显示关闭按钮。该按钮将关闭支付中心并将用户重定向到settings.return_url参数中指定的URL。默认为false。
}});
}});
ui.put("size", "large");
ui.put("theme", "default");
ui.put("version", "mobile");//设备的类型。可以是desktop(默认值)或mobile。
完整的请求体信息
Map<String, Object> xsollaParams = new HashMap<>();
xsollaParams.put("settings", new HashMap<String, Object>() {{
put("ui", ui);
put("return_url", constantInfo.getReturnUrl());
put("redirect_policy", new HashMap<String, String>() {
{
put("redirect_conditions", "successful");
}
});//回调触发
}});
xsollaParams.put("sandbox", true);//沙盒环境
xsollaParams.put("quantity", 1);
xsollaParams.put("custom_parameters", new HashMap<String, Object>() {{//项目特定参数。
put("character_id", userId);
}});
订单创建成功,返回
{
"order_id":32304580,
"token":"twpugyGEI56prN2fAzMKu5ynipYwXZqe_lc_cn_bg_FFFFFF_tb_3D46F5"
}
也可以使用服务端的为购买创建支付令牌,接入方式和客户端差不多
4. 支付
提示
直接访问 https://sandbox-secure.xsolla.com/paystation4/?token=TOKEN 即可跳转到付款页面,当然也可以用iframe中打开
使用上面的链接在沙盒模式下打开支付UI。项目发布后,请使用此URL:https://secure.xsolla.com/paystation4/?token=TOKEN。

选择paypal支付,可以用paypal沙盒虚拟账号支付,有关paypal账号部分参见java-paypal

在个人商户邮箱就可收到用户的付款信息

查询订单状态
可通过查询订单状态,确认是否完成付款
5. 通过发布商帐户进行管理
可以使用 发布商帐户 轻松管理付款:
- 在 会计 > 交易登记表 中查看交易历史记录、统计数据及上传交易数据。( 需要选择测试交易就能看见刚才测试的支付订单 )
- 在 会计 > 付款 中核对收入。
- 在 会计 > 报告 导出用于法律合规事宜的报告。
6. 退款
可以发起部分退款,也可以全额退款,这里只介绍全额退款,详细的文档请参见
https://developers.xsolla.com/zh/api/pay-station/operation/request-refund/
退款需要交易id,交易id
- 商户:商户后台交易记录能查看到交易id
- 用户:用户在付款后,ui页面有显示(№1163315218)
提示
merchant_id:商户id
transaction_id:交易id
@Override
@OperationLogger
public ReturnResult refundOrder(RefundOrderParams params) {
String userId = params.getUserId();
String orderId = params.getOrderId();
String gameId = params.getGameId();
String channelId = params.getChannelId();
String transcationId = params.getTranscationId();
String desc = params.getDesc();
//查询订单是否存在
OrderMeInfo orderMeInfo = OrderMeInfo.builder().gameId(gameId).channelId(channelId).orderId(orderId).userId(userId)
.orderStatus(ConstantCommon.ORDER_STATUS_1).build();
orderMeInfo = orderMeInfoMapper.selectOne(new QueryWrapper<>(orderMeInfo));
if (orderMeInfo == null) {
return ReturnResultError.builder().code(ConstantCommon.RETURN_CODE_903).msg("订单不存在或者不存在/已退款").data("")
.build();
}
//查询渠道配置信息
ConstantMeInfo constantInfo = getCacheConstantInfo(gameId, channelId, "xsolla");
//授权信息
String xsollaUserId = constantInfo.getUserId();//商户id
String appKey = constantInfo.getAppKey();//密钥
String headerBasic = OauthSignatureUtil.headerBasic(xsollaUserId, appKey);
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", headerBasic);
Map<String, Object> xsollaParams = new HashMap<>();
xsollaParams.put("description", "退款理由" + desc);
xsollaParams.put("email", "18712709017@163.com");//用户邮箱
Map<String, String> refund = client.postByJsonToMap("https://api.xsolla.com/merchant/v2/merchants/"
+ constantInfo.getUserId() + "/reports/transactions/" + transcationId + "/refund", headers, xsollaParams);
System.out.println(JSON.toJSONString(refund));
//TODO 更新订单信息
return ReturnResultSuccess.builder().code(ConstantCommon.RETURN_CODE_200).msg("退款成功").data(refund)
.count(ConstantCommon.RETURN_COUNT_1).build();
}
7. 设置WEBHOOK(重要)
如希望接收事件通知(如支付状态变化),请在发布商帐户中设置Webhook:
- 在发布商帐户 中打开您的项目。
- 在侧边栏中单击 项目设置 ,然后前往 Webhooks 。
- 将 Webhooks 开关设置为 开 。
- 指定Webhook URL。
- 默认会生成一个用于项目Webhook签名的密钥。如要生成一个新密钥,请单击刷新图标。
- 单击 保存设置 。
推荐实现以下Webhook:
要确认已收到Webhook,您的服务器必须作出如下响应:
- 不带消息正文的HTTP代码204。
- 描述问题的HTTP代码400(如果指定用户未找到或传入的签名无效)。
xsolla的接入到目前就已基本完成
- 本文作者: 景兴春
- 本文链接: https://www.jingxc.top/back/payment/java-xsolla.html
- 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!