说明
连连苹果支付Demo下载地址
https://apple.lianlianpay.com/OpenPlatform/sdk_download.jsp
连连苹果支付官方API说明(消费/预授权)
https://apple.lianlianpay.com/OpenPlatform/api_reference.jsp
说明文档
http://open.lianlianpay.com/wp-content/uploads/2014/05/%E8%BF%9E%E8%BF%9E%E6%94%AF%E4%BB%98%E6%89%8B%E6%9C%BA%E5%BA%94%E7%94%A8SDK%E5%8D%A1%E5%89%8D%E7%BD%AE%E6%A8%A1%E5%BC%8F%E5%95%86%E6%88%B7%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E%E4%B9%A6-2015-11-27-074831.pdf
Apple Pay在连连支付支持的 消费和预授权模式有什么区别?
预授权: 指特约商户向发卡机构取得持卡人30天内在不超过预授权金额一定比例范围的付款承诺,并在持卡人获取商品或接受服务后向发卡机构进行承兑的业务。通俗讲就是先冻结银行卡内部分资金用作押金,后按实际消费金额结算的业务。
消费: 消费者在商户进行消费时,直接按实际消费金额进行结算的业务。
开始集成
商户配置
static NSString *kLLOidPartner = @"201606301000000000"; // 商户号
static NSString *kLLPartnerKey = @"ABCDEFG"; // 私钥 在连连后台配置
static NSString *signType = @"MD5"; // 加密方式
static NSString *kAPMerchantID = @"merchant.com.apple.hehe"; // 与开发证书 MerchantID 保持一致
属性 及 代理
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIButton *payBtn; // 支付按钮
@property (nonatomic, retain) NSMutableDictionary *orderParam; // 订单配置字典
@property (nonatomic, strong) LLAPPaySDK *paySdk; // 连连SDK
@end
点击支付按钮执行支付方法
- (IBAction)toPay:(id)sender {
[self fillOrderMethodAndUserinfo];
self.orderParam = [self createOrder];
NSDictionary *orderParam = self.orderParam; // 创建订单
self.paySdk = [LLAPPaySDK sharedSdk]; // 创建SDK
self.paySdk.sdkDelegate = self; // 设置回调
// 连连加密订单的方法生成sign,如果和支付宝冲突无解就翻翻我发的文章吧
LLPayUtil *payUtil = [[LLPayUtil alloc] init];
orderParam = [payUtil signedOrderDic:orderParam andSignKey:kLLPartnerKey];
// 弹出苹果支付界面
[self.paySdk payWithTraderInfo:orderParam inViewController:self];
}
支付按钮的一些方法
- (NSMutableDictionary *)createOrder
{
NSDateFormatter *dateFormater = [[NSDateFormatter alloc] init];
[dateFormater setDateFormat:@"yyyyMMddHHmmss"];
NSString *simOrder = [dateFormater stringFromDate:[NSDate date]];
NSMutableDictionary *param = [NSMutableDictionary dictionary];
// 这里的dictionary参数全弄成字符串型,否则崩溃找不到错在哪了,本人在这里掉了很长时间的坑。。。
[param setDictionary:@{
@"sign_type" : signType, // 加密方式
@"busi_partner" : @"109001", // 虚拟商品销售:101001 实物商品销售:109001
@"dt_order" : simOrder, // 订单时间
@"notify_url" : @"http://test.yintong.com.cn:80/apidemo/API_DEMO/notifyUrl.htm", // 回调自家后台的stringURL
@"no_order" : @"123456", // 订单号
@"name_goods" : @"testName", // 商品名
@"info_order" : simOrder, // 备注
@"valid_order" : @"10080", // 订单有效时间 多长时间过期
@"user_id" : @"123", // 用户ID
}];
// 风险控制参数(参数需求按照文档表格)
// 文档地址 https://apple.lianlianpay.com/OpenPlatform/api_reference.jsp
NSString *phoneNum = @"13812345678";
NSDictionary *riskDict = @{
@"user_info_mercht_userno" : @"123",
@"user_info_dt_register" : @"123",
@"frms_ware_category" : @"4999", // 官方文档中有
@"user_info_bind_phone" : phoneNum,
};
param[@"risk_item"] = [LLPayUtil jsonStringOfObj:riskDict]; // 风控参数
param[@"money_order"] = @"0.01";
// 这两项一定写对,否则出错,如果出错在官方后台检查配置,同时检查苹果开发者网站
param[@"ap_merchant_id"] = kAPMerchantID; // 与苹果配置保持一直
param[@"oid_partner"] = kLLOidPartner; // 商户号
return param;
}
- (NSString*)fillOrderMethodAndUserinfo{
[self.orderParam removeObjectForKey:@"acct_name"];
[self.orderParam removeObjectForKey:@"id_no"];
[self.orderParam removeObjectForKey:@"no_agree"];
[self.orderParam removeObjectForKey:@"card_no"];
return nil;
}
Demo中的delegate方法 刚集成时务必复制,以便查找错误原因
- (void)paymentEnd:(LLPayResult)resultCode withResultDic:(NSDictionary *)dic
{
NSString *msg = @"支付异常";
switch (resultCode) {
case kLLPayResultSuccess:
{
msg = @"支付成功";
NSString* result_pay = dic[@"result_pay"];
if ([result_pay isEqualToString:@"SUCCESS"])
{
//
// NSString *payBackAgreeNo = dic[@"agreementno"];
//_agreeNumField.text = payBackAgreeNo;
}
else if ([result_pay isEqualToString:@"PROCESSING"])
{
msg = @"支付单处理中";
}
else if ([result_pay isEqualToString:@"FAILURE"])
{
msg = @"支付单失败";
}
else if ([result_pay isEqualToString:@"REFUND"])
{
msg = @"支付单已退款";
}
}
break;
case kLLPayResultFail:
{
msg = @"支付失败";
}
break;
case kLLPayResultCancel:
{
msg = @"支付取消";
}
break;
case kLLPayResultInitError:
{
msg = @"sdk初始化异常";
}
break;
case kLLPayResultInitParamError:
{
msg = dic[@"ret_msg"];
}
break;
default:
break;
}
NSString *showMsg = [msg stringByAppendingString:[LLPayUtil jsonStringOfObj:dic]];
[[[UIAlertView alloc] initWithTitle:@"结果"
message:showMsg
delegate:nil
cancelButtonTitle:@"确认"
otherButtonTitles:nil] show];
}
引用官方
以下是连连官方ReadMe整理格式后
LLPaySDK iOS接入指南
文件说明
- 内部包含 LLPay 的支付SDK
- LLPaySDK_iOS下载
- 连连 Pay SDK下载
- 文件夹内文件说明
文件 | 文件内容 |
---|---|
LLPaySdk.h | 头文件,声明接口 |
libPaySdkColor.a | 单独的LLPay 的 lib库 或者 单独的LLAPPay 的 lib库 |
walletResources.bundle | LianlianPay 资源包,请勿改名(如果是 Pay可不用) |
下面是基本的接入指南:
- 导入文件
- 添加头文件引用 #import "LLPaySdk.h"
- 设置link标志
- Target->Build Setting ,Other Linker Flags 设置为 -all_load
- 可能添加-all_load以后和其他库冲突,可以尝试使用 -force_load 单独load库, force_load后面跟的是 lib库的完整路径```
-force_load $(SRCROOT)/***/libPaySdkColor.a (****需要按照你的库放置的路径决定)
4. 调用sdk显示,注意retain修饰,自动释放以后,调用后会导致程序崩溃或者有些图片会消失(如导航栏返回图片等)
```
NSDictionary *orderParam = @{*****}; // 创建订单
self.sdk = [LLPaySdk sharedSdk]; // 创建SDK
self.sdk.sdkDelegate = self; // 设置回调
NSDictionary* signedDic = [payUtil signedOrderDic:orderParam andSignKey:md5key_or_rsakey] // 加过签名的订单字典
[self.sdk presentLLPaySDKInViewController: rootVC withPayType: LLPayTypeQuick andTraderInfo: signedDic];
```
> 接入什么类型的支付产品就传什么类型的payType,如果**LLPayType传错就会提示无此支付产品权限**
> 假如是ApplePay, 使用LLAPPaySDK,并在orderParam中设置**ap_merchant_id**
```
// 消费
- (void)payWithTraderInfo:(NSDictionary *)traderInfo
inViewController:(UIViewController *)viewController;
```
5. 编写结果回调
```
// 订单支付结果返回,主要是异常和成功的不同状态
- (void)paymentEnd:(LLPayResult)resultCode withResultDic:(NSDictionary *)dic
```
### LLPaySDK可配置部分
---
> iOS SDK可以通过修改资源bundle进行定制, 因为是在bundle里面,请在修改好以后 **clean proj**,这样才会生效。
1. 图片的替换,在内部的图片可以替换修改为自己的样式
2. 颜色等的修改,可以修改default.css文件,支持#abcdef,123,123,123两种颜色表示
3. 修改值意义列表
修改的对象 |修改方法
---|---
导航栏颜色 |替换ll_nav_bg3.png文件,以及修改css文件中NavBar字段(后面只表示字段,都是在default.css文件中)中的background-color
导航栏标题 |NavBar字段中的titleIconName; titleText
确认按钮 |#a-button
取消按钮 |#b-button
文本框 |UITextField
4. 参数字段部分
- 参数说明在demo中有,可以参考。字段名和wap不一致,请参考[demo(点击下载)](http://open.lianlianpay.com/wp-content/uploads/2014/08/LLPayDemo1230-2015-12-30-031859.zip)中的参数说明,参数中的user_id 不是商户号,是商户自己体系中的用户编号,前置卡输入时,no_agree是通过API查询得到的绑卡序号
5. 使用部分
- Demo中的输入项,是用来测试各种支付条件,包括认证支付(输入姓名,身份证),前置支付(输入卡号,协议号)。不是必须,请根据自己的支付方式测试。
- 支持银行数量,是根据支付类型以及商户来,可以配置,请联系运营。
### 常见问题
---
> **签名请尽量使用服务器端签名,假如使用客户端签名,请使用Demo中的payutil**
[连连支付对接常见问题](http://test.yintong.com.cn/asklianlian/)
1. **运行直接崩溃**
- 1、sdk没有retain保管。
- 2、sdk中使用了类扩展,请在other Linker Flags中添加 -all_load
2. **提示初始化错误**
- 1、检查环境和商户号等是否匹配;
- 2、检查签名方法是否正确(参考签名工具);
- 3、订单信息是否有遗漏项;
3. 所传的类型**不是NSString**
- 解释:连连的订单需要传入的订单格式为{“strkey”: “strvalue”, “strkey1″ : “strvalue2“},请不要传递 {“key”: [v1, v2]} 或者 {“key”: {“ikey”:”v”}} 这种
- 应对,修改订单内值的格式,特别是risk_item,需要变成 {“risk_item”:”{\”r_key\”:\”v\”}”}这样,由于有些信息商户是由后台传入,请*保证使用后台传给客户端的值也是NSString类型*
4. 商户**无此支付产品权限**
- 解释:我们的产品分为认证支付、快捷支付等多种支付方式。一种支付方式对应的包、支付调用方法、商户号都有所不同。
- 应对:先检查商户号是否是正确的商户号,比如 <认证支付测试商户号 201408071000001543> <快捷支付测试商户号 201408071000001546>
然后检查所对应的包或者调用方法对不对。
5. 商户**无此支付权限**
- 解释:一个商户号对应的商品业务类型是有限的。
- 应对:修改 商户业务类型 busi_partner 是 String(6)
- 虚拟商品销售:101001
- 实物商品销售:109001
- 外部账户充值:108001
6. 签名验证不对
- [签名验证错误解决](http://test.yintong.com.cn/asklianlian/?cat=10)
- 解释:签名有特定规则,订单里面的特定参数参与签名。
- 应对:ios最新的Demo中提供了payUtil函数,直接调用,就能生成签名正确的订单。然后再次提醒,我们**强烈建议商户在服务器端完成签名操作**。