开发指南
查询商品信息
这里的商品信息是指【苹果商品信息】、【谷歌商品信息】和 【Steam 商品信息】,不支持【网页商品信息】。通过此方法,传入对应平台的商品集合 productIds,可查询游戏在 Apple Store/Google Play/Steam 平台中设定的内购商品包含货币符号、货币价格等 sku 信息,具体信息可参见下文 商品数据结构定义。
- Android
- iOS
- Unity
- UE
/**
* 根据 product ids 查询商品列表
*
* @param productIds 需要查询的商品 ID 集合 (Google Play 定义的商品 ID)
* @param paymentCallback 支付结果回调
*/
XDGPayment.queryWithProductIds(List<String> productIds, XDGPaymentCallback<List<GoogleProductDetails>> paymentCallback)
/** 查询商品价格,请等待回调之后再做下一次查询,否则可能造成数据错乱
* @param productIds 需要查询的商品名数组
*/
NSArray *procudtIds = @[@"com.xd.sdkdemo1.stone30", @"com.xd.sdkdemo1.stone50"];
[XDGPayment queryWithProductIds:procudtIds completionHandler:^(NSArray<XDGProductInfo *> * _Nullable result, NSError * _Nullable error) {
if (error) {
NSLog(@"查询失败 %@", error);
} else {
// 查询成功, result 是查询结果
}
}];
XDGPayment.QueryWithProductIds(string[] productIds, info => {
if (info.xdgError != null){
} else{
}
});
FXDGPayment::QueryWithProductIds(
{/** Id array */},
FXDGProductInfo::FArrayDelegate::CreateLambda([](const TArray<FXDGProductInfo>& Infos) {
//成功
}),
FXDGError::FDelegate::CreateLambda([](const FXDGError& Error) {
//失败
}));
商品数据结构定义
- Android
- iOS
- Unity
- UE
public class GoogleProductDetails {
private GoogleProductDetails() {
}
/**
* 原始 json 字符串
*/
private String originString;
/**
* 商品描述
*/
private String description;
/**
* 商品名称
*/
private String name;
/**
* 商品 ID
*/
private String productId;
/**
* Google 结算库 BillingClient.ProductType 的类型: BillingClient.ProductType.INAPP(inapp)、BillingClient.ProductType.SUBS(subs)
*/
private String productType;
/**
* 正在销售的产品的标题
*/
private String title;
/**
* 一次性购买商品详情
*/
private GoogleOneTimePurchaseOfferDetails googleOneTimePurchaseOfferDetails;
/**
* 获取商品描述
* @return 商品描述
*/
public String getDescription() {
return description;
}
/**
* 获取商品名称
* @return 商品名称
*/
public String getName() {
return name;
}
/**
* 获取商品 ID
* @return 商品 ID
*/
public String getProductId() {
return productId;
}
/**
* 获取商品类型
* @return 商品类型(Google 结算库 BillingClient.ProductType 的类型: BillingClient.ProductType.INAPP(inapp)、BillingClient.ProductType.SUBS(subs) 的具体值)
*/
public String getProductType() {
return productType;
}
/**
* 获取正在销售的产品的标题
* @return 正在销售的产品的标题
*/
public String getTitle() {
return title;
}
/**
* 获取一次性商品详细信息
* @return 一次性商品详细信息
*/
public GoogleOneTimePurchaseOfferDetails getGoogleOneTimePurchaseOfferDetails() {
return googleOneTimePurchaseOfferDetails;
}
/**
* 原始 json 字符串
* @return String
*/
@NonNull
@Override
public String toString() {
return originString;
}
/**
* 一次性商品数据结构定义
*/
public static class GoogleOneTimePurchaseOfferDetails {
/**
* 格式化的付款价格,包括其货币符号
*/
private final String formattedPrice;
/**
* 以微单位表示的支付价格,其中 1,000,000 微单位等于一个货币单位。
*/
private final long priceAmountMicros;
/**
* ISO 4217 货币代码的价格
*/
private final String priceCurrencyCode;
/**
* 返回带有货币符号的价格
* @return formatted price for the payment, including its currency sign
*/
public String getFormattedPrice() {
return formattedPrice;
}
/**
* 返回 1 微分为单位的价格
* @return the price for the payment in micro-units, where 1,000,000 micro-units equal one unit of the currency.
*/
public long getPriceAmountMicros() {
return priceAmountMicros;
}
/**
* 返回 ISO 4217 标准的价格
* @return ISO 4217 currency code for price.
*/
public String getPriceCurrencyCode() {
return priceCurrencyCode;
}
}
}
@interface XDGProductInfo : NSObject
// 本地化商品描述
@property(nonatomic,strong,readonly) NSString *localizedDescription;
// 本地化商品标题
@property(nonatomic,strong,readonly) NSString *localizedTitle;
// 价格
@property(nonatomic,strong,readonly) NSDecimalNumber *price;
// 价格本地化信息(包含货币符号等)
@property(nonatomic,strong,readonly) NSLocale *priceLocale;
// 商品ID
@property(nonatomic,strong,readonly) NSString *productIdentifier;
@end
// Unity 在不同平台返回的商品类型相同,但字段不同
#if UNITY_IOS
[Serializable]
public class SkuDetailBean
{
// 本地化商品描述
public string localizedDescription;
// 本地化商品标题
public string localizedTitle;
// 价格
public double price;
// 商品ID
public string productIdentifier;
// 本地化标识
public string localeIdentifier;
// 价格本地化信息(包含货币符号等)
public PriceLocale priceLocale;
}
#elif UNITY_ANDROID
[Serializable]
public class SkuDetailBean
{
// 原始 json 字符串
private string _originString;
// 商品描述
public string description;
// 商品名称
public string name;
// 商品 ID
public string productId;
// Google 结算库 BillingClient.ProductType 的类型: BillingClient.ProductType.INAPP(inapp)、BillingClient.ProductType.SUBS(subs)
public string productType;
// 正在销售的产品的标题
public string title;
// 一次性购买商品详情
public GoogleOneTimePurchaseOfferDetails googleOneTimePurchaseOfferDetails;
}
#else
public class SkuDetailBean
{
// 商品名称
public string ProductSkuName { get; set; }
// 商品sku
public string ProductSkuCode { get; set; }
// 商品描述
public string Desc { get; set; }
// 渠道商品sku
public string ChannelSkuCode { get; set; }
// 货币
public string Currency { get; set; }
// 地区
public string Region { get; set; }
// 原价
public double CostPrice { get; set; }
// 现价
public double SalePrice { get; set; }
}
#endif
struct XDGPAYMENT_API FXDGProductInfo
{
//苹果支付
#if PLATFORM_IOS
/** 本地化商品描述 */
FString LocalizedDescription;
/** 本地化商品标题 */
FString LocalizedTitle;
/** 价格 */
double Price;
struct FPriceLocale
{
FString LocaleIdentifier;
FString LanguageCode;
FString CountryCode;
FString ScriptCode;
FString CalendarIdentifier;
FString DecimalSeparator;
FString CurrencySymbol;
};
/** 价格本地化信息(包含货币符号等) */
FPriceLocale PriceLocale;
/** 商品ID */
FString ProductIdentifier;
#endif
//谷歌支付
#if PLATFORM_ANDROID
/** 原始 json 字符串 */
FString OriginString;
/** 商品描述 */
FString Description;
/** 商品名称 */
FString Name;
/** 商品 ID */
FString ProductId;
/** Google 结算库 BillingClient.ProductType 的类型: BillingClient.ProductType.INAPP(inapp)、BillingClient.ProductType.SUBS(subs) */
FString ProductType;
/** 正在销售的产品的标题 */
FString Title;
struct GoogleOneTimePurchaseOfferDetails
{
FString FormattedPrice;
long PriceAmountMicros = 0;
FString PriceCurrencyCode;
};
/** 一次性购买商品详情 */
GoogleOneTimePurchaseOfferDetails OneTimePurchaseOfferDetails;
//Steam支付
#elif PLATFORM_WINDOWS || PLATFORM_MAC
#if defined ENABLE_STEAM_LOGIN
/** 商品名称 */
FString productSkuName;
/** 商品sku */
FString productSkuCode;
/** 商品描述 */
FString desc;
/** 渠道商品sku */
FString channelSkuCode;
/** 货币 */
FString currency;
/** 地区 */
FString region;
/** 原价 */
double costPrice = 0.0;
/** 现价 */
double salePrice = 0.0;
#endif
#endif
};
商品支付
这里支付指的是【苹果支付】,【谷歌支付】和【Steam 支付】
- 苹果和谷歌支付需要同时在苹果或谷歌后台和 XDSDK 平台中配置商品信息,在接口中使用的 productId 为苹果或谷歌后台的商品 ID
- Steam 支付则只需要在 XDSDK 平台配置商品信息,在接口中使用的 productId 为平台配置的商品 ID
SDK 会在对应平台调用 Apple/Google/Steam 的支付进行商品的购买。游戏传入的 orderId 、serverId、roleId、ext 字段会在支付完成时通过 s2s 的形式透传回游戏的 Server 端以便游戏可对支付进行校验。
- 这里的回调只当做【支付完成】看待,【支付成功】需要对接XDServer后,以服务端推送信息为准。
- 由于 Apple 支付票据有概率会出现多票据合并的情况,此时会丢失游戏传入的 orderId,并由平台随机生成一个唯一的 orderId。
- Android
- iOS
- Unity
- UE
/**
* 商品支付
*
* @param orderId 订单 ID。游戏侧订单号,服务端支付回调会包含该字段,如无该字段,传空
* @param productId 商品 ID。Google Play 定义的商品 ID
* @param roleId 角色 ID。支付角色 ID,服务端支付回调会包含该字段
* @param serverId 服务器 ID。所在服务器 ID,不能有特殊字符,服务端支付回调会包含该字段
* @param ext 附加信息。服务端支付回调会包含该字段
* @param paymentCallback 支付结果回调
*/
XDGPayment.payWithProduct(String orderId, String productId, String roleId, String serverId, String ext, XDGPaymentCallback<Object> paymentCallback);
/**
* @param orderId 订单 ID。游戏侧订单号,服务端支付回调会包含该字段。如果无,传空字符串。
* @param productId 商品 ID。到 AppStore 购买的商品 ID
* @param roleId 角色 ID。支付角色 ID,服务端支付回调会包含该字段
* @param serverId 服务器 ID。所在服务器 ID,不能有特殊字符,服务端支付回调会包含该字段
* @param ext 透传参数。服务端支付回调会包含该字段。可用于标记区分充值回调地址 (此字段长度不能超过 255 个字符)
* @param completionHandler 支付结果处理
*/
[XDGPayment payWithOrderId:@"" productId:productId roleId:roleId serverId:serverId ext:@"gagag" completionHandler:^(XDGOrderInfo * _Nonnull orderInfo, NSError * _Nonnull error) {
if (error) {
// 支付失败
} else {
// 支付成功,为了确保可靠性,建议支付成功对接服务端回调
}
}];
/**
* @param orderId 订单 ID。游戏侧订单号,服务端支付回调会包含该字段。如果无,传空字符串。
* @param productId 商品 ID。到 AppStore 购买的商品 ID
* @param roleId 角色 ID。支付角色 ID,服务端支付回调会包含该字段
* @param serverId 服务器 ID。所在服务器 ID,不能有特殊字符,服务端支付回调会包含该字段
* @param ext 透传参数。服务端支付回调会包含该字段。可用于标记区分充值回调地址 (此字段长度不能超过 255 个字符)
* @param callback 支付结果处理
*/
XDGPayment.PayWithProduct(string orderId, string productId, string roleId, string serverId, string ext, Action<XDGOrderInfoWrapper> callback);
FXDGOrderInfo::FDelegate CompleteBlock = FXDGOrderInfo::FDelegate::CreateLambda([](const FXDGOrderInfo& OrderInfo) {
});
FXDGError::FDelegate ErrorDelegate = FXDGError::FDelegate::CreateLambda([](const FXDGError& Error) {
});
/**
* @param OrderIDStr 订单 ID。游戏侧订单号,服务端支付回调会包含该字段。如果无,传空字符串。
* @param ProductIDStr 商品 ID。到 AppStore 购买的商品 ID
* @param RoleIDStr 角色 ID。支付角色 ID,服务端支付回调会包含该字段
* @param ServerIDStr 服务器 ID。所在服务器 ID,不能有特殊字符,服务端支付回调会包含该字段
* @param ExtStr 透传参数。服务端支付回调会包含该字段。可用于标记区分充值回调地址 (此字段长度不能超过 255 个字符)
* @param CompleteBlock 支付成功结果处理
* @param ErrorDelegate 支付错误结果处理
*/
FXDGPayment::PayWithProduct(OrderIDStr, ProductIDStr, RoleIDStr, ServerIDStr, ExtStr, CompleteBlock, ErrorDelegate);
订单数据结构定义
- Android
- iOS
- Unity
- UE
@interface XDGOrderInfo : NSObject
/// 游戏侧订单号
@property (nonatomic,copy,readonly) NSString *outTradeNo;
/// 商品 ID
@property (nonatomic,copy,readonly) NSString *productIdentifier;
/// 角色所在服务器 ID
@property (nonatomic,copy,readonly) NSString *serverId;
/// 角色 ID
@property (nonatomic,copy,readonly) NSString *roleId;
/// 当前订单所用货币
@property (nonatomic,copy,readonly) NSString *currency;
/// 当前订单价格
@property (nonatomic,strong,readonly) NSDecimalNumber *price;
@end
public class XDGOrderInfo
{
// 游戏侧订单号
public string orderId;
// 商品 ID
public string productId;
// 角色 ID
public string roleId;
// 角色所在服务器 ID
public string serverId;
// 透传参数
public string ext;
}
struct XDGPAYMENT_API FXDGOrderInfo
{
/** 订单号 */
FString OrderId;
/** 商品 ID */
FString ProductId;
/** 角色所在服务器ID */
FString ServerId;
/** 角色 ID */
FString RoleId;
};
网页支付(Android、PC)
安卓未上架 Google Play 平台的游戏或者 PC 平台的游戏可使用网页支付的形式进行游戏内的商品购买,同样的游戏定义的商品信息需要在平台中进行配置。 在网页支付中,因支付渠道回调可能存在延迟或用户误触关闭按钮的缘故,SDK 的支付回调的含义仅包含「支付完成」、「支付取消」、「其他错误」,游戏可通过回调作为触发点,通过轮询的方式查询支付最终的结果。
这里的回调也是当做【支付完成】看待,【支付成功】需要对接 XDServer 后,以服务端推送信息为准!
- Android
- Unity
- UE
/**
* 网页支付
*
* @param orderId 订单 ID。游戏侧订单号,服务端支付回调会包含该字段,如无该字段,传空。
* @param productId 商品 ID。游戏的商品ID,必填
* @param productName 商品名称。用于内嵌支付内部显示,必填
* @param payAmount 商品价格,必填
* @param roleId 角色 ID。支付角色 ID,服务端支付回调会包含该字段,必填
* @param serverId 服务器 ID。所在服务器 ID,不能有特殊字符,服务端支付回调会包含该字段,必填
* @param extras 附加信息。服务端支付回调会包含该字段,必填
* @param paymentCallback 支付结果回调
*/
XDGPayment.payWithWeb(String orderId,
String productId,
String productName,
double payAmount,
String roleId,
String serverId,
String extras,
XDGPaymentCallback<Object> paymentCallback);
public static class PaymentResponseCode {
public final static int OK = 0x00000000; // 支付完成
public final static int ERROR = 0xffffffff; // 支付错误
public final static int NETWORK_ERROR = 0xfffffffe; // 网络错误
public final static int USER_CANCEL = 0x00000001; // 支付取消
public final static int PURCHASE_PROCESSING = 0x00000002; // 支付处理中
}
XDGPayment.PayWithWeb(
orderId,
productId,
productName,
price,
roleId,
serverId,
extras,
(type, msg) => {
});
type:
OK 完成
Cancel 取消
Processing 处理中
Error 失败
public class PaymentConstants
{
public static class PaymentResponseCode
{
public static int OK = 0; // 支付完成
public static int ERROR = -1; // 支付错误
public static int NETWORK_ERROR = -2; // 网络错误
public static int USER_CANCEL = 1; // 用户取消
public static int PURCHASE_PROCESSING = 2; // 支付处理中
}
}
FXDGPayment::FPayResultCodeDelegate Delegate = FXDGPayment::FPayResultCodeDelegate::CreateLambda([](EXDGPayResultCode ResultCode, const FString& Message) {
FString Result = "Unknow Code";
if (ResultCode == EXDGPayResultCode::OK) {
Result = TEXT("支付完成");
} else if (ResultCode == EXDGPayResultCode::Error) {
Result = TEXT("支付错误");
} else if (ResultCode == EXDGPayResultCode::NetworkError) {
Result = TEXT("网络错误");
} else if (ResultCode == EXDGPayResultCode::UserCancel) {
Result = TEXT("支付取消");
} else if (ResultCode == EXDGPayResultCode::PurchaseProcessing) {
Result = TEXT("支付处理中");
}
});
FXDGPayment::PayWithWeb(ServerIDStr, RoleIDStr, ProductIDStr, OrderIDStr, ProductNameStr, PayAmount, ExtrasStr, Delegate);
Android 原生支付(国内)
XDSDK 在 6.10.1 的版本开始针对 Android 平台增加了支付宝、微信的原生支付,内部会判断是否在 TapTap 沙盒
或 TapTap 云玩
环境,在此环境会继续走网页支付的流程,游戏在国内环境中可调用下列方法进行支付宝、微信的原生支付。
- Android
- iOS
- Unity
- UE
// 支付参数指定
PayDetailsParams params = PayDetailsParams.newBuilder()
.setGameOrderId(orderId) // 游戏订单 ID。游戏侧订单号,服务端支付回调会包含该字段,不建议为空,如无该字段,传空
.setProductId(productId) // 游戏商品 ID。不可为空
.setProductName(productName) // 游戏商品名称。走 Web 支付时 UI 预显示字段,可为空
.setPayAmount(payAmount) // 商品价格。单位(元),走 Web 支付时 UI 预显示字段,可为 0
.setRoleId(roleId) // 游戏角色 ID。支付角色 ID,服务端支付回调会包含该字段
.setServerId(serverId) // 游戏服务器 ID。所在服务器 ID,不能有特殊字符,服务端支付回调会包含该字段
.setExt(ext) // 附加参数。服务端支付回调会包含该字段
.build();
// SDK 内置 UI 支付
XDGPayment.pay(params, new XDGPaymentCallback<Object>() {
@Override
public void onPaymentCallback(XDGPaymentResult result, Object data) {
if (result != null) {
int code = result.code;
if (com.xd.intl.payment.constant.Constants.PaymentResponseCode.OK == code) {
// 支付成功
} else if (com.xd.intl.payment.constant.Constants.PaymentResponseCode.USER_CANCEL == code) {
// 支付取消
} else {
// 支付失败
Log.e("支付失败:code = " + code + ", message = " + result.debugMessage)
}
}
}
});
String payType = PayType.WECHAT_PAY // 指定微信支付方式,支付宝支付方式为:PayType.ALIPAY
// 无 UI 支付
XDGPayment.pay(payType, params, new XDGPaymentCallback<Object>() {
@Override
public void onPaymentCallback(XDGPaymentResult result, Object data) {
if (result != null) {
int code = result.code;
if (com.xd.intl.payment.constant.Constants.PaymentResponseCode.OK == code) {
// 支付成功
} else if (com.xd.intl.payment.constant.Constants.PaymentResponseCode.USER_CANCEL == code) {
// 支付取消
} else {
// 支付失败
Log.e("支付失败:code = " + code + ", message = " + result.debugMessage)
}
}
}
});
// 该方法仅针对 Android 平台,iOS 暂不支持。
/// <summary>
/// 微信支付和支付宝支付的原生实现,带 UI 方式
/// </summary>
/// <param name="orderId"> 游戏订单 ID。游戏侧订单号,服务端支付回调会包含该字段,不建议为空,如无该字段,传空。</param>
/// <param name="productId">游戏商品 ID,不可为空</param>
/// <param name="productName">游戏商品名称,走 Web 支付时 UI 预显示字段,可为空</param>
/// <param name="payAmount">商品价格,单位(元),走 Web 支付时 UI 预显示字段,可为 0</param>
/// <param name="roleId">游戏角色 ID,支付角色 ID,服务端支付回调会包含该字段</param>
/// <param name="serverId">游戏服务器 ID,所在服务器 ID,不能有特殊字符,服务端支付回调会包含该字段</param>
/// <param name="ext">附加信息。服务端支付回调会包含该字段</param>
/// <param name="callback">支付回调:正常支付完成信息会在 callback.orderInfo 中,如果发生错误会在 callback.xdgError 字段中进行提示</param>
public static void Pay(string orderId,
string productId,
string productName,
double payAmount,
string roleId,
string serverId,
string ext,
Action<XDGOrderInfoWrapper> callback);
// 下面是带 UI 方式的示例代码
var orderId = "your_order_id";
var productId = "your_product_id";
var productName = "your_product_name";
double payAmount = 0.2;// your_price
var roleId = "player_role_id";
var serverId = "your_server_id";
var ext = "your_ext";
XDGPayment.Pay(
orderId,
productId,
productName,
payAmount,
roleId,
serverId,
ext,
(x) => {
if (x == null){
Debug.LogErrorFormat( $"PayWithUI 支付结果: NULL");
}
else{
var errorMsg = x.xdgError?.error_msg ?? "NULL";
var orderInfo = JsonUtility.ToJson(x.orderInfo) ?? "NULL";
Debug.LogFormat( $"PayWithUI 支付结果: {orderInfo} 错误信息:{errorMsg}");
}
});
/// <summary>
/// 微信支付和支付宝支付的原生实现,不带 UI 方式
/// </summary>
/// <param name="payType">游戏订单支付方式,目前一共有 2 种:Alipay-支付宝;WechatPay-微信支付</param>
/// <param name="orderId">游戏订单 ID。游戏侧订单号,服务端支付回调会包含该字段,不建议为空,如无该字段,传空</param>
/// <param name="productId">游戏商品 ID,不可为空</param>
/// <param name="productName">游戏商品名称,走 Web 支付时 UI 预显示字段,可为空</param>
/// <param name="payAmount">商品价格,单位(元),走 Web 支付时 UI 预显示字段,可为 0</param>
/// <param name="roleId">游戏角色 ID,支付角色 ID,服务端支付回调会包含该字段</param>
/// <param name="serverId">游戏服务器 ID,所在服务器 ID,不能有特殊字符,服务端支付回调会包含该字段</param>
/// <param name="ext">附加信息。服务端支付回调会包含该字段</param>
/// <param name="callback">支付回调:正常支付完成信息会在 callback.orderInfo 中,如果发生错误会在 xdgError 字段中进行提示</param>
public static void Pay(PayType payType,
string orderId,
string productId,
string productName,
double payAmount,
string roleId,
string serverId,
string ext,
Action<XDGOrderInfoWrapper> callback);
// 下面是不带 UI 方式的示例代码
var payType = PayType.Alipay;//PayType.Alipay-支付宝,PayType.WechatPay-微信
var orderId = "your_order_id";
var productId = "your_product_id";
var productName = "your_product_name";
double payAmount = 0.2;// your_price
var roleId = "player_role_id";
var serverId = "your_server_id";
var ext = "your_ext";
XDGPayment.Pay(
payType,
orderId,
productId,
productName,
payAmount,
roleId,
serverId,
ext,
(x) => {
if (x == null){
Debug.LogErrorFormat( $"PayWithUI 支付结果: NULL");
}
else{
var errorMsg = x.xdgError?.error_msg ?? "NULL";
var orderInfo = JsonUtility.ToJson(x.orderInfo) ?? "NULL";
Debug.LogFormat( $"PayWithUI 支付结果: {orderInfo} 错误信息:{errorMsg}");
}
});
FXDGPayDetailsParams Params;
Params.GameOrderId = TEXT("游戏订单 ID"); // 游戏订单 ID。游戏侧订单号,服务端支付回调会包含该字段,不建议为空,如无该字段,传空。
Params.ProductId = TEXT("游戏商品 ID"); // 游戏商品 ID,不可为空
Params.ProductName = TEXT("游戏商品名称"); // 游戏商品名称,走 Web 支付时 UI 预显示字段,可为空
Params.PayAmount = 0; // 商品价格,单位(元),走 Web 支付时 UI 预显示字段,可为 0
Params.RoleId = TEXT("游戏角色 ID"); // 游戏角色 ID,支付角色 ID,服务端支付回调会包含该字段
Params.ServerId = TEXT("游戏服务器 ID"); // 游戏服务器 ID,所在服务器 ID,不能有特殊字符,服务端支付回调会包含该字段
Params.Ext = TEXT("附加参数"); // 附加信息。服务端支付回调会包含该字段
FXDGPayment::FPayResultCodeDelegate Delegate = FXDGPayment::FPayResultCodeDelegate::CreateLambda([](EXDGPayResultCode ResultCode, const FString& Message) {
FString Result = "Unknow Code";
if (ResultCode == EXDGPayResultCode::OK) {
Result = TEXT("支付完成");
} else if (ResultCode == EXDGPayResultCode::Error) {
Result = TEXT("支付错误");
} else if (ResultCode == EXDGPayResultCode::NetworkError) {
Result = TEXT("网络错误");
} else if (ResultCode == EXDGPayResultCode::UserCancel) {
Result = TEXT("支付取消");
} else if (ResultCode == EXDGPayResultCode::PurchaseProcessing) {
Result = TEXT("支付处理中");
}
});
// SDK 内置 UI 支付
FXDGPayment::Pay(Params, Delegate);
// 无 UI 支付
EXDGPayType PayType = EXDGPayType::WeChatPay; // 指定微信支付方式,支付宝支付方式为:EXDGPayType::AliPay
FXDGPayment::Pay(PayType, Params, Delegate);
应用外购买或掉单
当游戏需要支持 Apple 提供的商店兑换码(暂不支持 Google 商店)进行内购或者处理异常情况下的消费掉单时,需要使用如下的两个方法进行处理。
首先使用查询接口获取当前已知的兑换码订单或者掉单数据,游戏需要通过返回结果内的数据来和玩家确认商品信息和发放角色,然后使用兑换或补单接口进行订单确认和消费。
查询订单数据
- Android
- iOS
- Unity
- UE
// 暂不支持
[XDGPayment queryRestoredPurchases:^(NSArray<XDGTransactionInfo *> * _Nonnull result) {
}];
// 查询礼包码或掉单数据
XDGPayment.QueryRestoredPurchase(restoredPurchases =>
{
if (restoredPurchases == null || restoredPurchases.Count == 0)
{
// 没有需要恢复的购买
}
else
{
foreach (var restoredPurchase in restoredPurchases)
{
// 此处仅为方便展示使用 foreach,实际支付请替换成队列或其他形式,不要在一个订单还没消费完成前进行下一笔消费。
string productId = restoredPurchase.productId;
if ("礼包码对应的商品ID".Equals(productId))
{
// 礼包码发放确认弹窗,用户确认之后走 XDGPayment.RestorePurchase 消费订单
}
else
{
// 掉单数据发放确认弹窗,用户确认之后走 XDGPayment.RestorePurchase 消费订单
}
}
}
});
FXDGPayment::QueryRestoredPurchases(FXDGTransactionInfo::FArrayDelegate::CreateLambda([Printer, this](const TArray<FXDGTransactionInfo>& Infos)
{
// Infos 是返回的交易信息
}));
礼包码兑换或掉单补单
在上述方法中返回的未完成订单,游戏可传入对应的参数进行 Apple/Google 的商品消费确认以保证用户购买的商品正常使用。
- Android
- iOS
- Unity
- UE
// 暂不支持
XDGTransactionInfo *transInfo = [[XDGTransactionInfo alloc] init];
[transInfo setValue:transactionIdentifier forKey:@"transactionIdentifier"];
[transInfo setValue:productIdentifier forKey:@"productIdentifier"];
[XDGPayment restorePurchase:transInfo orderId:orderId roleId:roleId serverId:serverId ext:ext completionHandler:^(XDGOrderInfo * _Nonnull orderInfo, NSError * _Nonnull error) {
}];
XDGPayment.RestorePurchase(string purchaseToken, string orderId, string productId, string roleId, string serverId, string ext, Action<XDGOrderInfoWrapper> callback);
FXDGPayment::RestorePurchase({{'FXDGPayment::QueryRestoredPurchases' 中返回的交易信息的其中一个}}, OrderIDStr, RoleIDStr, ServerIDStr, ExtStr,
FXDGOrderInfo::FDelegate::CreateLambda([Printer, this](const FXDGOrderInfo& OrderInfo)
{
// 成功
}), FXDGError::FDelegate::CreateLambda([Printer, this](const FXDGError& Error)
{
// 失败
}));