iOS SDK开发接入
文档版本:0.2.1
SDK版本:3.1.3
目录
1. 开发接入指南
该部分文档主要介绍如何在您的开发项目中引入SDK,首次接入SDK的开发人员可以通过该章节快速掌握SDK的部署流程。
1.1 获取最新版SDK
SHA-256 Digest: ead47a005d080a58816178133c39e18c787818c8b49752482b152b7c1c9dcb00
为保证您的财产和数据安全,请勿使用从其他非收钱吧渠道获取的SDK。对由于使用了非官方SDK而导致的任何物质或非物质损失,收钱吧概不负责。
1.2 集成SDK
1.2.1 iOS支持
目前iOS SDK支持的iOS版本为 iOS 7.0+ 。
1.2.2 向项目中添加SDK
只需解压您下载的SDK文件,其中应包含WSUpayKit.framework和WSUpayKit.bundle两个文件。WSUpayKit.framework中包含了SDK的全部代码,WSUpayKit.bundle中包含了SDK所用到的所有视图、多语言支持和多媒体等资源。请将这两个文件拖拽至您的iOS开发项目中,并确保Copy items if needed
和您的目标是被勾选的,如下图所示。
1.2.3 向目标中添加依赖
SDK需要的依赖如下:
- Security.framework
- CoreLocation.framework
- libz.dylib
请选择您的目标 -> Build Phases -> Link Binary With Libraries
,单击+
按钮。如下图所示:
在弹出的窗口中搜索Security.framework和CoreLocation.framework,然后确认添加。
添加libz.dylib依赖时,请在弹出的窗口中点击Add Other...
,会弹出资源管理器窗口,此时按下Cmd + Shift + G
,在输入框中输入/usr/lib
,然后进入该文件夹。选中libz.dylib,点击确定后,即完成该步骤。
1.2.4 更新项目设置
Info部分
在您的项目中,选择您的目标 -> Info -> Custom iOS Target Properties
,在其中加入以下属性:
Supported interface orientations (iPhone)
(可选)App Transport Security Settings -> Allow Arbitrary Loads
Privacy - Location Usage Description
NSLocationWhenInUseUsageDescription
如需要使用标准界面模式,请将Supported interface orientations (iPhone)
设置为Portrait
方向,因为SDK的标准界面在iPhone设备上仅支持Portrait方向。
自iOS 9起,苹果对安全性提出更高要求,因此请将App Transport Security Settings
中Allow Arbitrary Loads
的值设为YES
,以便开发模式时使用HTTP连接。在发布正式版本时,可根据实际需要将该设置取消。
此外,为了保证交易安全,SDK需要获取用户的当前的地理位置位置,因此需要在Privacy - Location Usage Description
和NSLocationWhenInUseUsageDescription
中设置提醒文字,否则SDK将无法正常工作。
具体配置如下图所示:
Build Settings部分
在您的项目中,选择您的目标 -> Build Settings -> Linking
,请确认Other Linker Flags
中包含-ObjC
。如下图所示:
1.2.5 在代码中引用SDK
#import <WSUpayKit/WSUpayKit.h>
仅需该一行代码,您就可以在代码中轻松使用SDK了。
2. 开发者文档
本章节详尽全面地介绍了SDK中所有开发者可以使用的类,类成员,NS_ENUM及其他常量。
2.1 WSUpayOrder
SDK订单类,代表所需操作的订单对象。
2.1.1 属性成员
成员 | 类型 | 修饰 | 说明 |
sn | NSString | strong, nonatomic | 收钱吧系统内部唯一订单号,由数字组成,不超过16字符 |
client_sn | NSString | strong, nonatomic | 商户系统订单号,必须在商户系统内唯一,不超过64字符 |
total_amount | NSInteger | assign, nonatomic | 交易总金额,以分为单位,不超过10位,超过1亿元的收款请使用银行转账 |
payway | WSUpayPayway | assign, nonatomic | 支付渠道,如微信、支付宝、京东钱包、百度钱包和QQ钱包等 |
dynamic_id | NSString | strong, nonatomic | 支付条码内容,不超过32字符 |
subject | NSString | strong, nonatomic | 本次交易的简要介绍,不超过64字符 |
order_description | NSString | strong, nonatomic | 对商品或本次交易的描述,不超过256字符 |
order_operator | NSString | strong, nonatomic | 发起本次交易的操作员,不超过32字符 |
extended | NSDictionary | strong, nonatomic | 合码云与特定第三方单独约定的参数字典,最多支持24个字段,每个字段key长度不超过64字符,value长度不超过256字符,总长度不超过64字符 |
reflect | NSString | strong, nonatomic | 反射参数,任何调用者希望原样返回的信息,不超过64字符 |
refund_request_no | NSString | strong, nonatomic | 商户退款所需序列号,防止重复退款,不超过32字符 |
refund_amount | NSInteger | assign, nonatomic | 退款金额,以分为单位,不超过10位 |
2.1.2 该类无方法成员
2.2 WSUpayActivationInfo
SDK激活信息类,代表包含激活设备所需信息的对象。
2.2.1 属性成员
成员 | 类型 | 修饰 | 说明 |
code | NSString | strong, nonatomic | 由合码云提供的设备激活码,用于激活该设备作为合码云服务的终端 |
vendor_sn | NSString | strong, nonatomic | 服务商编号,由收钱吧提供,请妥善保管 |
vendor_key | NSString | strong, nonatomic | 服务商秘钥,由收钱吧提供,请妥善保管 |
vendor_app_id | NSString | strong, nonatomic | 服务商应用的ID,由服务商通过服务商平台创建 |
client_sn | NSString | strong, nonatomic | 服务商给该终端指定的编号,不超过50字符 |
name | NSString | strong, nonatomic | 服务商给该终端的命名,不超过64字符 |
2.2.2 该类无方法成员
2.3 WSUpayTask
SDK任务。配置好任务后,调用相关方法,可对合码云的订单进行一系列操作。
2.3.1 属性成员
成员 | 类型 | 修饰 | 说明 |
upayOrder | WSUpayOrder | readonly, strong, nonatomic | 本次任务需要执行的订单 |
upayActivationInfo | WSUpayActivationInfo | readonly, strong, nonatomic | 本次终端激活任务需要执行的激活信息 |
finishBlock | WSUpayTaskFinishBlock | copy | 处理任务结果或错误信息的block |
preCreateBlock | WSUpayTaskFinishBlock | copy | 处理预下单的订单信息(其中包含收款二维码)或错误信息的block |
devMode | BOOL | assign, nonatomic | 是否使用开发模式。有关开发模式,请参见附录 |
needsUserInterface | BOOL | assign, nonatomic | 是否需要使用SDK的标准界面模式 |
baseViewController | UIViewController | weak, nonatomic | 如需使用标准界面模式,请将其设置为当前的ViewController |
refundByClientSn | BOOL | assign, nonatomic | 使用SDK标准界面模式进行退款时,是否将用户输入的交易单号作为商户订单号 (若为YES,退款时SDK将把用户输入的交易单号当作商户订单号;否则当作合码云订单号) |
revokeByClientSn | BOOL | assign, nonatomic | 使用SDK标准界面模式进行撤单时,是否将用户输入的交易单号作为商户订单号 (若为YES,撤单时SDK将把用户输入的交易单号当作商户订单号;否则当作合码云订单号) |
2.3.2 初始化方法成员
2.3.2.1 根据订单信息进行初始化
- (instancetype)initWithUpayOrder:(WSUpayOrder *)upayOrder;
按传入的WSUpayOrder,初始化并返回WSUpayTask实例。
参数
upayOrder | 需要进行操作的WSUpayOrder对象 |
返回值
一个包含upayOrder的WSUpayTask对象。
适用性
SDK 3.0.0
2.3.2.2 根据订单信息和回调处理block进行初始化
- (instancetype)initWithUpayOrder:(WSUpayOrder *)upayOrder
onFinish:(WSUpayTaskFinishBlock)finish;
按传入的WSUpayOrder和交易完成后的处理逻辑,初始化并返回WSUpayTask实例。
参数
upayOrder | 需要进行操作的WSUpayOrder对象 |
finish | 交易结果返回的处理block |
返回值
一个包含upayOrder的WSUpayTask对象。当任何交易操作完成后,该对象会回调finish。
适用性
SDK 3.0.0
2.3.2.3 根据订单信息、预下单返回处理block和交易完成后的处理block进行初始化
- (instancetype)initWithUpayOrder:(WSUpayOrder *)upayOrder
onPreCreate:(WSUpayTaskFinishBlock)preCreate
onFinish:(WSUpayTaskFinishBlock)finish;
按传入的WSUpayOrder、预下单返回处理逻辑和交易完成后的处理逻辑,初始化并返回WSUpayTask实例。
参数
upayOrder | 需要进行操作的WSUpayOrder对象 |
preCreate | 预下单结果返回的处理block |
finish | 交易结果返回的处理block |
返回值
一个包含upayOrder的WSUpayTask对象。当预下单结果返回后,该对象会回调preCreate,当任何交易操作完成后,该对象会回调finish。
适用性
SDK 3.0.0
2.3.2.4 根据激活信息和回调block进行初始化
- (instancetype)initWithUpayActivationInfo:(WSUpayActivationInfo *)upayActivationInfo
onFinish:(void (^)(NSError *error))finish;
按传入的WSUpayActivationInfo,初始化WSUpayTask对象。
参数
upayActivationInfo | 合码云支付网关接收的激活信息对象 |
finish | 激活结果返回的处理block |
返回值
一个包含upayActivationInfo的WSUpayTask对象。当激活操作完成后,该对象会回调finish。
适用性
SDK 3.1.1
2.3.3 类(静态)方法成员
2.3.3.1 SDK版本接口
+ (NSString *)sdkVersion;
获取SDK的版本号。
参数
N/A
返回值
SDK的版本号,例如"3.1.1"
。
适用性
SDK 3.1.1
2.3.4 实例方法成员
2.3.4.1 [DEPRECATED]旧版激活接口
- (void)activateTerminal:(NSString *)code
vendorId:(NSString *)vendorId
vendorKey:(NSString *)vendorKey
finish:(void (^)(NSError *error))finish;
激活该设备。在该设备首次被用于SDK付款时调用,否则该设备将无法进行正常交易。
参数
code | 由合码云提供的设备激活码,用于激活该设备作为合码云服务的终端 |
vendorId | 合码云服务商ID,验证服务商身份的重要凭证,由开发者和服务商管理,请在应用内确保其安全性 |
vendorKey | 合码云服务商KEY,验证服务商身份的重要凭证,由开发者和服务商管理,请在应用内确保其安全性 |
finish | 激活结果处理的block,成功激活后返回的NSError为nil ,激活失败时返回NSError实例 |
返回值
N/A
适用性
SDK 3.0.0
2.3.4.2 激活接口
- (void)activate;
向合码云支付网关发送终端激活请求,35秒超时。若超时未收到响应,则返回激活失败。
参数
N/A
返回值
N/A
适用性
SDK 3.1.1
2.3.4.3 支付(B扫C)接口
- (void)pay;
向合码云服务器发起支付请求。若超时未收到响应,则发起查询。若规定时间内查询未果则自动冲正(撤单)。
参数
N/A
返回值
N/A
适用性
SDK 3.0.0
2.3.4.4 退款接口
- (void)refund;
向合码云服务器发起退款请求。若超时未收到响应,则发起查询并返回查询结果。
参数
N/A
返回值
N/A
适用性
SDK 3.0.0
2.3.4.5 查询接口
- (void)query;
向合码云服务器发起查询订单请求
参数
N/A
返回值
N/A
适用性
SDK 3.0.0
2.3.4.6 预下单(C扫B)接口
- (void)preCreate;
向合码云支付网关发送预下单请求。首次回调返回二维码,二次回调返回支付结果。
参数
N/A
返回值
N/A
适用性
SDK 3.0.0
2.3.4.7 撤单接口
- (void)revoke;
向合码云支付网关发送撤单请求。若超时未收到响应,则发起查询并返回查询结果。
参数
N/A
返回值
N/A
适用性
SDK 3.0.0
2.3.4.8 设备激活状态接口
- (BOOL)currentDeviceActivated;
获取当前设备的激活状态。
参数
N/A
返回值
若当前设备已激活,返回YES
;否则返回NO
。
适用性
SDK 3.1.1
2.3.4.9 设备编号接口
- (NSString *)terminalSerialNumber;
获取当前设备的(合码云)终端编号。
参数
N/A
返回值
若当前设备已激活,返回该设备的(合码云)终端编号;否则返回nil
。
适用性
SDK 3.1.1
2.4 WSUpayResult
SDK交易结果类,包含操作完成后返回的订单信息和交易结果。
2.4.1 属性成员
成员 | 类型 | 修饰 | 说明 |
sn | NSString | strong, nonatomic | 合码云系统内部唯一订单号,由数字组成,不超过16字符 |
client_sn | NSString | strong, nonatomic | 商户系统订单号,必须在商户系统内唯一,不超过64字符 |
order_status | NSString | strong, nonatomic | 订单状态,当前订单状态,不超过32字符 |
total_amount | NSInteger | assign, nonatomic | 交易总金额,以分为单位,不超过10位 |
net_amount | NSInteger | assign, nonatomic | 剩余金额,实收金额减已退款金额,以分为单位,不超过10位 |
payway | WSUpayPayway | assign, nonatomic | 支付渠道,如微信、支付宝、京东钱包、百度钱包和QQ钱包等 |
sub_payway | WSUpaySubPayway | assign, nonatomic | 支付方式,扫描条形码支付或预下单二维码收款 |
payer_uid | NSString | strong, nonatomic | 付款人ID,支付渠道(微信,支付宝等)中的付款人ID,不超过64字符 |
payer_login | NSString | strong, nonatomic | 付款人账号,支付渠道(微信,支付宝等)中的付款人账号,不超过128字符 |
trade_no | NSString | strong, nonatomic | 支付渠道(微信,支付宝等)的交易流水号 |
client_tsn | NSString | strong, nonatomic | 商户交易序列号,不超过32字符 |
finish_time | double | assign, nonatomic | 上次操作在合码云服务器的完成时间,Unix时间戳,精确到毫秒 |
channel_finish_time | double | assign, nonatomic | 上次操作在支付渠道(微信,支付宝等)完成的时间,Unix时间戳,精确到毫秒 |
qr_code | NSString | strong, nonatomic | 收款二维码信息,预下单时在订单信息中返回,不超过128字符 |
subject | NSString | strong, nonatomic | 本次交易的简要介绍,不超过64字符 |
order_description | NSString | strong, nonatomic | 对商品或本次交易的描述,不超过256字符 |
order_operator | NSString | strong, nonatomic | 发起本次交易的操作员,不超过32字符 |
reflect | NSString | strong, nonatomic | 反射参数,任何调用者希望原样返回的信息,不超过64字符 |
2.4.2 该类无方法成员
2.5 WSUpayTaskFinishBlock
SDK定义的处理任务结果或错误信息的block类型,WSUpayTask的finishBlock
和preCreateBlock
属性的类型均为该类型。该类型声明如下:
typedef void (^WSUpayTaskFinishBlock)(WSUpayResult *upayResult, NSError *error);
- 当任意操作正常完成时,WSUpayTask回调时传入正常的WSUpayResult实例以及
nil
的NSError; - 当操作失败时,传入包含错误信息的NSError实例,并根据情况,尽可能返回WSUpayResult实例。
2.6 WSUpayPayway
SDK定义了名为WSUpayPayway的NS_ENUM,常量类型为NSInteger,方便开发者指定和判断订单的支付渠道。
支付渠道 | 实际值 | 说明 |
WSUpayPaywayUnknown | 0 | 未知支付渠道 |
WSUpayPaywayAlipay | 1 | 支付宝 |
WSUpayPaywayWechat | 3 | 微信支付 |
WSUpayPaywayBaidu | 4 | 百度钱包 |
WSUpayPaywayJD | 5 | 京东钱包 |
WSUpayPaywayQQ | 6 | QQ钱包 |
2.7 WSUpaySubPayway
SDK定义了名为WSUpaySubPayway的NS_ENUM,常量类型为NSInteger,方便开发者指定和判断订单的支付方式。
支付方式 | 实际值 | 说明 |
WSUpaySubPaywayBarcode | 1 | 付款条形码支付方式 |
WSUpaySubPaywayQrcode | 2 | 收款二维码支付方式 |
2.8 WSUpayGeneralErrorCode
SDK定义了名为WSUpaySubPayway的NS_ENUM,常量类型为NSInteger,方便开发者根据SDK返回的NSError中的code
属性判断错误原因。
错误代码 | 实际值 | 说明 |
WSUpayGeneralErrorCodeExternalError | -10200 | 支付渠道返回了处理异常时的错误代码 |
WSUpayGeneralErrorCodeResponseError | -10300 | SDK无法处理收钱吧服务返回参数时的错误代码 |
WSUpayGeneralErrorCodeClientError | -10400 | 客户端请求无效的错误代码 |
WSUpayGeneralErrorCodeServerError | -10500 | 合码云服务器端处理出现异常的错误代码 |
WSUpayGeneralErrorCodeTerminalError | -10600 | 终端设备错误代码 |
WSUpayGeneralErrorCodeUnknownError | -11000 | 未知错误代码 |
2.9 其他常量
2.9.1 SDK自定义Error Domain
SDK定义了一组类型为NSString的Error Domains,方便开发者根据SDK返回的NSError中的domain
属性判断错误原因。
Error Domain | 实际值 | 说明 |
WSUpayRequestErrorDomain | WSUpayRequestErrorDomain | 请求参数错误 |
WSUpayTerminalErrorDomain | WSUpayTerminalErrorDomain | 终端错误 |
WSUpayNetworkErrorDomain | WSUpayNetworkErrorDomain | 网络错误 |
WSUpayServerErrorDomain | WSUpayServerErrorDomain | 服务器错误 |
WSUpayTransactionErrorDomain | WSUpayTransactionErrorDomain | 业务流程错误 |
WSUpayUnknownErrorDomain | WSUpayUnknownErrorDomain | 合码云SDK未知错误 |
2.9.2 收钱吧订单状态
SDK定义了一组类型为NSString的订单状态常量,方便开发者根据SDK返回的WSUpayResult中的order_status
属性判断当前合码云订单的状态。
订单状态 | 实际值 | 说明 |
WSUpayOrderCreated | CREATED | 订单已创建 |
WSUpayOrderPaid | PAID | 订单已成功支付 |
WSUpayOrderPayCanceled | PAY_CANCELED | 订单未支付,已被撤消 |
WSUpayOrderPayError | PAY_ERROR | 订单支付失败,付款结果未知 |
WSUpayOrderRefunded | REFUNDED | 订单已被全额退款 |
WSUpayOrderPartialRefunded | PARTIAL_REFUNDED | 订单已部分退款 |
WSUpayOrderRefundError | REFUND_ERROR | 订单退款失败,退款结果未知 |
WSUpayOrderCanceled | CANCELED | 订单支付失败,已冲正 |
WSUpayOrderCancelError | CANCEL_ERROR | 订单冲正失败,状态未知 |
WSUpayOrderRevoked | CANCELED | 订单已撤单 |
WSUpayOrderRevokeError | CANCEL_ERROR | 订单撤单失败,状态未知 |
3. 开发指引及示例
3.1 激活
激活操作提供了无界面和标准界面两种开发模式。当指定needsUserInterface
为YES
且baseViewController
为当前的ViewController时,则启用标准界面模式;否则启用无界面模式。
WSUpayTask实例的activate
方法调用前,需要利用激活信息初始化方法指定设备的激活信息(upayActivationInfo
)和回调处理block(finish
)。
upayActivationInfo
的code
属性是由合码云提供的设备激活码,用于激活该设备作为合码云服务的终端。而vendor_sn
和vendor_key
是验证服务商身份的重要凭证,由开发者和服务商管理,请在应用内确保其安全性。vendor_app_id
是为了在服务商开发了多款基于合码云SDK的应用产品时便于区分和管理。client_sn
和name
是为了便于服务商或商户对激活好的终端进行辨认。
finish
参数是处理激活结果的block。当激活成功时,SDK会回调block并传入nil
;激活失败时,SDK会回调block并传入包含错误信息的NSError实例。若缺少finish
,则activate
方法不执行任何操作。
激活参数
WSUpayActivationInfo的属性中有关支付操作的属性如下:
属性 | 无界面模式 | 标准界面模式 |
vendor_sn | 必填 | 必填 |
vendor_key | 必填 | 必填 |
vendor_app_id | 必填 | 必填 |
code | 必填 | 代码无需填写,界面输入框必填 |
client_sn | 选填 | 代码无需填写,界面输入框选填 |
name | 选填 | 代码无需填写,界面输入框选填 |
示例代码
#import "ViewController.h"
#import <WSUpayKit/WSUpayKit.h>
@interface ViewController
@property (strong, nonatomic) WSUpayTask *upayTask;
@end
@implementation ViewController
/**
@brief 利用SDK激活该设备,以便进行交易
*/
- (void)activateTerminal {
WSUpayActivationInfo *upayActivationInfo = [[WSUpayActivationInfo alloc] init];
upayActivationInfo.vendor_sn = @"someSn";
upayActivationInfo.vendor_key = @"someKey";
upayActivationInfo.vendor_app_id = @"someId";
// upayActivationInfo.code = @"someCode"; // 无界面模式下需要预先指定激活码
// upayActivationInfo.client_sn = @"someClientSn"; // 无界面模式下需要预先指定商户终端编号
// upayActivationInfo.name = @"someName"; // 无界面模式下需要预先指定终端名称
_upayTask = [[WSUpayTask alloc] initWithUpayActivationInfo:upayActivationInfo
onFinish:^(NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error) {
// 激活失败,展示激活失败结果
} else {
// 激活成功,展示激活成功结果
}
});
}];
_upayTask.needsUserInterface = YES; // 启用标准界面模式
_upayTask.baseViewController = self;
_upayTask.devMode = YES; // 使用开发模式
[_upayTask activate];
}
@end
3.3 支付
支付操作提供了无界面和标准界面两种开发模式。当指定needsUserInterface
为YES
且baseViewController
为当前的ViewController时,则启用标准界面模式;否则启用无界面模式。
在准备支付请求时,对于WSUpayOrder实例的支付渠道(payway
)属性,开发者可以选择不指定或赋值为WSUpayPaywayUnknown
,合码云服务器会根据WSUpayOrder实例的dynamic_id
属性自动判断支付渠道。
若开发者使用无界面开发模式,则由开发者负责开发扫描条码页面,并指定WSUpayOrder实例的支付条码(dynamic_id
)属性,否则支付请求会直接返回参数错误。若开发者使用标准界面开发模式,则由SDK负责展示扫描条码页面并收集扫描到的条码值。
支付参数
WSUpayOrder的属性中有关支付操作的属性如下:
属性 | 无界面模式 | 标准界面模式 |
client_sn | 必填 | 必填 |
total_amount | 必填 | 必填 |
payway | 选填 | 选填 |
dynamic_id | 必填 | 选填 |
subject | 必填 | 必填 |
order_description | 选填 | 选填 |
order_operator | 必填 | 必填 |
extended | 选填 | 选填 |
reflect | 选填 | 选填 |
示例代码
#import "ViewController.h"
#import <WSUpayKit/WSUpayKit.h>
@interface ViewController
@property (strong, nonatomic) WSUpayTask *upayTask;
@end
@implementation ViewController
/**
@brief 利用SDK进行扫码支付交易
*/
- (void)payOrder {
WSUpayOrder *order = [[WSUpayOrder alloc] init];
order.client_sn = @"8128258306";
order.total_amount = 100; // 1元,单位为分
order.payway = WSUpayPaywayWechat; // 支付渠道,详见附录
order.subject = @"Dinner Order";
order.order_operator = @"John Doe";
order.order_description = @"Pumpkin Pie";
order.reflect = @"Send me back";
_upayTask = [[WSUpayTask alloc] initWithUpayOrder:order
onFinish:^(WSUpayResult *upayResult, NSError *error) {
if (error) {
// 交易失败,处理错误信息
if (upayResult) {
// 处理交易失败的订单
}
} else {
// 交易完成,处理交易结果
// 可根据upayResult.order_status判断当前的订单状态
}
}];
_upayTask.needsUserInterface = YES; // 启用标准界面模式
_upayTask.baseViewController = self;
_upayTask.devMode = YES; // 使用开发模式
[_upayTask pay];
}
@end
3.4 退款
退款操作提供了无界面和标准界面两种开发模式。当指定needsUserInterface
为YES
且baseViewController
为当前的ViewController时,则启用标准界面模式;否则启用无界面模式。
在退款时,对WSUpayOrder实例的收钱吧订单号(sn
)和商户订单号(client_sn
)属性处理方式如下:
- 当开发者同时指定了两者时,退款以合码云订单号为准;
- 当仅指定两者任意其一时,按照指定的订单号为准;
- 若都未指定,则在无界面模式下,退款操作直接返回参数校验错误,在标准界面模式下,SDK会展示输入订单号的控件。
在最后一种情形时,WSUpayTask的refundByClientSn
属性是用来让开发者选择在标准界面模式下,用户输入的订单号是否作为商户订单号。
此外,若使用标准界面模式,开发者也可以选择不指定WSUpayOrder实例的退款金额(refund_amount
),此时SDK会展示输入退款金额控件。
退款参数
WSUpayOrder的属性中有关退款操作的属性如下:
属性 | 无界面模式 | 标准界面模式 |
sn | 选填 | 选填,与client_sn必填其一 |
client_sn | 选填 | 选填,与sn必填其一 |
refund_request_no | 必填 | 必填 |
refund_amount | 必填 | 选填 |
order_operator | 选填 | 选填 |
reflect | 选填 | 选填 |
示例代码
#import "ViewController.h"
#import <WSUpayKit/WSUpayKit.h>
@interface ViewController
@property (strong, nonatomic) WSUpayTask *upayTask;
@end
@implementation ViewController
/**
@brief 利用SDK进行退款操作
*/
- (void)refundOrder {
WSUpayOrder *order = [[WSUpayOrder alloc] init];
order.sn = @"7892249408175";
order.client_sn = @"8128258306";
order.refund_request_no = @"1234567890";
order.refund_amount = 100; // 1元,单位为分
order.order_operator = @"John Doe";
order.reflect = @"Send me back";
_upayTask = [[WSUpayTask alloc] initWithUpayOrder:order
onFinish:^(WSUpayResult *upayResult, NSError *error) {
if (error) {
// 退款失败,处理错误信息
if (upayResult) {
// 处理退款失败的订单
}
} else {
// 退款完成,处理退款结果
// 可根据upayResult.order_status判断当前的订单状态
}
}];
_upayTask.needsUserInterface = YES; // 启用标准界面模式
_upayTask.baseViewController = self;
_upayTask.devMode = YES; // 使用开发模式
_upayTask.refundByClientSn = NO;
[_upayTask refund];
}
@end
3.5 预下单
预下单操作提供了无界面和标准界面两种开发模式。当指定needsUserInterface
为YES
且baseViewController
为当前的ViewController时,则启用标准界面模式;否则启用无界面模式。
在准备预下单请求时,对于WSUpayOrder实例的支付渠道(payway
)属性,开发者必须指定,且值不可为WSUpayPaywayUnknown
。否则SDK会直接回调preCreate并传入参数错误。
若开发者使用无界面开发模式,则由开发者负责开发展示收款二维码页面。若开发者使用标准界面开发模式,则由SDK负责展示收款二维码页面。
目前合码云预下单订单的有效期大约为 100 秒,若超时仍未支付,则收款二维码失效。
预下单参数
WSUpayOrder的属性中有关预下单操作的属性如下:
属性 | 无界面模式 | 标准界面模式 |
client_sn | 必填 | 必填 |
total_amount | 必填 | 必填 |
payway | 必填 | 必填 |
subject | 必填 | 必填 |
order_description | 选填 | 选填 |
order_operator | 必填 | 必填 |
extended | 选填 | 选填 |
reflect | 选填 | 选填 |
示例代码
#import "ViewController.h"
#import <WSUpayKit/WSUpayKit.h>
@interface ViewController
@property (strong, nonatomic) WSUpayTask *upayTask;
@end
@implementation ViewController
/**
@brief 利用SDK进行预下单交易
*/
- (void)preCreateOrder {
WSUpayOrder *order = [[WSUpayOrder alloc] init];
order.client_sn = @"8128258306";
order.total_amount = 100; // 1元,单位为分
order.payway = WSUpayPaywayAlipay; // 支付渠道,详见附录
order.subject = @"Grocery Order";
order.order_operator = @"Sam White";
order.order_description = @"Paper Towel";
order.extended = @{@"return_url": @"http://www.somewebsite.com/"};
order.reflect = @"Send me back";
_upayTask = [[WSUpayTask alloc] initWithUpayOrder:order
onPreCreate:^(WSUpayResult *upayResult, NSError *error) {
if (error) {
// 预下单失败,处理错误信息
if (upayResult) {
// 处理预下单失败的订单
}
} else {
// 预下单完成,处理预下单结果
// 若使用无界面模式,展示收款二维码
}
}
onFinish:^(WSUpayResult *upayResult, NSError *error) {
if (error) {
// 交易失败,处理错误信息
if (upayResult) {
// 处理交易失败的订单
}
} else {
// 交易完成,处理交易结果
// 可根据upayResult.order_status判断当前的订单状态
}
}];
_upayTask.needsUserInterface = YES; // 启用标准界面模式
_upayTask.baseViewController = self;
_upayTask.devMode = YES; // 使用开发模式
[_upayTask preCreate];
}
@end
3.6 查询
查询操作仅支持无界面开发模式。开发者仅需传入WSUpayOrder实例,并指定其合码云订单号(sn
)或商户订单号(client_sn
)属性。若都未指定,则SDK直接返回参数错误。
查询参数
WSUpayOrder的属性中有关查询操作的属性如下:
属性 | 无界面模式 | 标准界面模式 |
sn | 选填 | 选填,与client_sn必填其一 |
client_sn | 选填 | 选填,与sn必填其一 |
示例代码
#import "ViewController.h"
#import <WSUpayKit/WSUpayKit.h>
@interface ViewController
@property (strong, nonatomic) WSUpayTask *upayTask;
@end
@implementation ViewController
/**
@brief 利用SDK进行查询操作
*/
- (void)queryOrder {
WSUpayOrder *order = [[WSUpayOrder alloc] init];
order.sn = @"7892249408175";
order.client_sn = @"8128258306";
_upayTask = [[WSUpayTask alloc] initWithUpayOrder:order
onFinish:^(WSUpayResult *upayResult, NSError *error) {
if (error) {
// 查询失败,处理错误信息
} else {
// 查询完成,处理查询结果
}
}];
_upayTask.devMode = YES; // 使用开发模式
[_upayTask query];
}
@end
3.7 撤单
撤单操作提供了无界面和标准界面两种开发模式。当指定needsUserInterface
为YES
且baseViewController
为当前的ViewController时,则启用标准界面模式;否则启用无界面模式。
在撤单时,对WSUpayOrder实例的合码云订单号(sn
)和商户订单号(client_sn
)属性处理方式如下:
- 当开发者同时指定了两者时,撤单以收钱吧订单号为准;
- 当仅指定两者任意其一时,按照指定的订单号为准;
- 若都未指定,则在无界面模式下,撤单操作直接返回参数校验错误,在标准界面模式下,SDK会展示输入订单号的控件。
在最后一种情形时,WSUpayTask的revokeByClientSn
属性是用来让开发者选择在标准界面模式下,用户输入的订单号是否作为商户订单号。
撤单参数
WSUpayOrder的属性中有关撤单操作的属性如下:
属性 | 无界面模式 | 标准界面模式 |
sn | 选填 | 选填,与client_sn必填其一 |
client_sn | 选填 | 选填,与sn必填其一 |
reflect | 选填 | 选填 |
示例代码
#import "ViewController.h"
#import <WSUpayKit/WSUpayKit.h>
@interface ViewController
@property (strong, nonatomic) WSUpayTask *upayTask;
@end
@implementation ViewController
/**
@brief 利用SDK进行撤单操作
*/
- (void)revokeOrder {
WSUpayOrder *order = [[WSUpayOrder alloc] init];
order.sn = @"7892249408175";
order.client_sn = @"8128258306";
_upayTask = [[WSUpayTask alloc] initWithUpayOrder:order
onFinish:^(WSUpayResult *upayResult, NSError *error) {
if (error) {
// 撤单失败,处理错误信息
if (upayResult) {
// 处理撤单失败的订单
}
} else {
// 撤单完成,处理撤单结果
// 可根据upayResult.order_status判断当前的订单状态
}
}];
_upayTask.needsUserInterface = YES; // 启用标准界面模式
_upayTask.baseViewController = self;
_upayTask.devMode = YES; // 使用开发模式
_upayTask.revokeByClientSn = NO;
[_upayTask revoke];
}
@end
4 附录
4.1 开发模式
为了方便开发者进行调试,SDK提供了 开发模式 。开发模式下,设备端和服务器端都采用开发环境的数据和参数。这样可以避免开发者因开发调试而影响到正式环境的商户交易数据。因此,合码云建议开发者在开发调试和发布测试版本时,采用开发模式;在发布正式版本时,则采用非开发模式。
SDK在WSUpayTask中提供了devMode
属性。该属性决定当前操作是否使用开发模式。若在执行操作前,设置WSUpayTask的devMode
属性为YES
,则:
- SDK将调用合码云开发环境服务器,所有交易数据保存在开发环境,与正式环境隔离;
- SDK将使用开发环境的终端配置。这意味着如果开发者在开发模式下成功激活某台设备后,切换到非开发模式下,该设备仍处于未激活状态。
4.2 无界面模式
如果开发者产品设计和开发能力较强,且希望最大程度自定义用户界面和交互流程,可以选择无界面开发模式。该模式下,所有操作均不会展示SDK自带的用户界面,而仅通过回调与集成SDK的应用沟通。有关如何开启或关闭无界面模式,请参考开发指引及示例。
4.3 标准界面模式
如果开发者不希望投入过多成本,且希望使用标准化用户界面和交互流程,可以选择标准界面开发模式。该模式下,除查询操作以外,均会展示SDK自带的用户界面。该模式可以极大降低开发和维护成本,同时保证用户使用SDK的体验。有关如何开启或关闭标准界面模式,请参考开发指引及示例。
4.4 SDK返回错误处理
SDK在操作过程中遇到任何异常时,会将错误信息通过回调方式传递NSError实例给开发者处理。SDK同时定义了一系列错误代码及Error Domain分别作为NSError实例的code
和domain
的值,以便开发者判断错误的原因。
此外,SDK还会设置NSError实例中的userInfo
属性,传入包含NSLocalizedDescriptionKey
和NSLocalizedFailureReasonErrorKey
键值对的NSDictionary实例,其中带有当前错误的详细描述和错误原因描述,方便开发者在调试时获取更详细的错误信息。
下表用于说明各种常见错误信息的处理方法:
domain | code | 处理方法 |
WSUpayTransactionErrorDomain | -10200 | 合码云服务器成功处理,但支付渠道业务处理异常,请检查您的交易请求是否合法以及交易双方账户的有效性。 |
WSUpayTerminalErrorDomain | -10400 -10600 |
服务器认为该终端设备不合法或设备激活失败。若为激活操作,请确认您的激活码有效;若为其他操作,请确认设备已被正常激活。 |
WSUpayRequestErrorDomain | -10400 | 无效的请求。请确认您的请求参数是否合法,具体请参考开发指引及示例 |
WSUpayServerErrorDomain | -10300 -105xx |
服务器返回结果异常或服务器端处理异常。出现该错误时,操作最终结果未知。当收款或退款时遇到该错误,建议开发者提示用户联系合码云客服。 |
WSUpayUnknownErrorDomain | -10500 -11000 或其他 |
未知错误。出现该错误时,操作最终结果未知。当收款或退款时遇到该错误,建议开发者提示用户联系合码云客服。调试时可检查userInfo 属性确认错误原因。 |
除以上错误信息以外,在遇到网络通信错误、JSON解析错误和Keychain错误等异常时,SDK还会返回domain
为NSURLErrorDomain
、NSCocoaErrorDomain
和com.samsoffes.sskeychain
的NSError实例。
5. 常见问题
5.1 在支付、预下单或退款时,为何未收到任何回调?
解决方案:
首先请确保您的项目添加了正确的依赖并完成了以下设置(具体步骤请参考开发接入指南):
Privacy - Location Usage Description
NSLocationWhenInUseUsageDescription
其次,检查代码,确保WSUpayTask的finishBlock
传入了正确的处理逻辑(预下单时需要检查preCreateBlock
)。
最后,请确保WSUpayTask的实例在操作过程中没有被ARC(Objective-C / Swift)机制回收(例如可以将WSUpayTask的实例作为当前ViewController的一个strong的属性)。
注:如果您在开发时遇到任何问题需要咨询,请 联系我们
6. 联系我们
如果您在使用SDK进行开发时遇到任何问题,请及时联系合码云技术支持。