最新《ApplePay支付》接入
2016-02-26 11:09
387 查看
前言:
2016是个真正开始走向解放钱包的时代了,从各种卡片开始流行起,不管你用的是磁条卡还是芯片卡,肯定是慢慢的塞满了你的钱包,但随着2月18日Apple Pay在中国上线,越来越多的人开始使用。Apple Pay 是行业称呼,也有叫苹果支付,其实它叫连连付。下面,我们就进入接入前的准备环节。
准备:
Apple Pay的接入相对支付宝简单,对于微信更是简单。但是,Apple Pay的接入流程可以说是和微信支付是半亲。为什么说是半亲?因为Apple Pay的重点接入和微信的第二词签名是80%一样的。对于准备也是所有支付里面最难的一种。困难的种类:
1、Apple Pay 的正式支付网站还不可以登录。同时他们也给出了,跨域登录和动态登录。
2、这里我们要登录(正式登录)为了签名秘钥获取及IP域名配置。后续再说(不能正式登录就不能获得秘钥)。
3、现在有一个测试登录入口。
4、登录后,你的工作就来了。请看下图(3相里面的内容没有点开,怕吓着人了)。
5、下面进行的也是重要的也是很麻烦的。我就用语言描述了,就不上图了(图,后续完善)。首先,你要登录苹果开发者账号。进入证书模块。如果是第一次的话。你的MerchantID 这个模块是没有东西的。我们要进行添加。添加的时候会让你写两个东西。分别是:MerchantID 和 BundleID。然后,你进行在连连付的账户里创建应用,如下图:
其中BundelID 和你开发者账号里面生成MerchantID 的时候要一样。第二步是提交,你开发者中心里面你填写的MerchantID 。第三步,你下载一个CRS 的文件。保存到重要的位置。然后。我们现在要切换到,苹果开发者中心证书生生模块。在这个模块里面,进行证书的创建。在第三步的时候,会让你提交一个CRS文件。这个文件就是,你刚才下在的文件。(后续完善)。
6、我们进行工程的配置。
1.我们要导入必要的支持库(保证,支付的安全,定位)。要导入的库如下:
2.我们要进行开发SDK 的导入。(这里我将其融合)
3.我们要挑选开发者。
4.进入项目Build Seting 里面的OtherLinkerFlags 设置为 _all_load.
5.进入项目 CApAbilities 模块,打开Apple Pay模块。并点击更新按钮。成功后会有三个对号。同时项目里面会出现一个证书。如下图:
第一:我们进行效果展示。
第二:功能介绍
1、动态的边框。
2、TableView的独立创建,界面。
3、Pay支付和Auth的预授权。
第二:代码的编写。
1.进行订单的签名,和部分算法代码。
签名代码:
-(NSString*)GetString:(NSDictionary*)anyobjiect_dict{
//
创建一个局部数组,防止OrderInfoAllKeysArray
为空
NSArray * AllKeys =@[@"busi_partner",@"dt_order",@"info_order",
@"money_order",@"name_goods",@"no_order",
@"notify_url",@"oid_partner",@"risk_item",@"sign_type",
@"valid_order"];
if (self.OrderInfoAllKeysArray !=nil)
{
//
如果OrderInfoAllKeysArray
存在将 Allkeys 替代
AllKeys = self.OrderInfoAllKeysArray;
}
if (ErrorMessageDictInfo) {
[ErrorMessageDictInfosetObject:@"OrderInfoAllKeysArray没有传入"forKey:@"AllKeys"];
}
// 将一个不可变的数组,可变化。进行数组对象字母排序
NSMutableArray * LetterKeysArray = [NSMutableArrayarrayWithArray:AllKeys];
[LetterKeysArray sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1,
id _Nonnull obj2) {
return [obj1
compare:obj2];
}];
// 声明一个可变的字符串,将字典转化为字符串
NSMutableString * PiecedMutableString = [[NSMutableStringalloc]initWithCapacity:0];
for (NSString * tempstrin LetterKeysArray) {
if ([anyobjiect_dict[tempstr]
length] != 0) {
[PiecedMutableString appendFormat:@"&%@=%@",tempstr,anyobjiect_dict[tempstr]];
}
}
// 进行可变的字符串进行处理
if (PiecedMutableString.length !=0) {
//
删除字符串的第一个字符:@“&”
[PiecedMutableString deleteCharactersInRange:NSMakeRange(0,1)];
}else{
if(ErrorMessageDictInfo){
[ErrorMessageDictInfosetObject:@"65行可变字符串不存在"forKey:@"PiecedMutableString"];
}
}
if ([anyobjiect_dict[@"sign_type"]isEqualToString:@"MD5"]) {
//
拼接上签名的Key-Value
[PiecedMutableString appendFormat:@"&key=%@",self.SingKey];
}
// 声明要输出的字符串对象
NSString * Return_SignString =
nil;
if([anyobjiect_dict[@"sign_type"]isEqualToString:@"MD5"]){
Return_SignString = [ApplePayAlgorithm
GetMd5String:PiecedMutableString];
}else{
//
哈希加密
Return_SignString = [ApplePayAlgorithm
signHmacString:PiecedMutableString withKey:self.SingKey];
}
#ifdef kLLPayUtilNeedRSASign
id<LLPDataSigner> signer = LLPCreateRSADataSigner(self.signKey);
signString = [signer signString:paramString];
#endif
// 输出加密后的字符串
NSLog(@"签名字符串:%@",Return_SignString);
return Return_SignString;
}
2.加密算法代码
MD5
+(NSString*)GetMd5String:(NSString*)anyobject_string{
// 进行编码转换成字符
const char *original_str = [anyobject_stringUTF8String];
unsigned char result[32];
CC_MD5(original_str, (CC_LONG)strlen(original_str), result);//调用md5
NSMutableString * MD5_String = [NSMutableStringstring];
for (int i =0; i <
16; i++){
[ MD5_String appendFormat:@"%02x", result[i]];
}
return MD5_String;
}
哈希
+ (NSString *)signHmacString:(NSString*)text withKey:(NSString*)key{
constchar *cKey = [keycStringUsingEncoding:NSUTF8StringEncoding];
constchar *cData = [textcStringUsingEncoding:NSUTF8StringEncoding];
uint8_t cHMAC[CC_SHA256_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA256, cKey,strlen(cKey), cData,
strlen(cData), cHMAC);
NSString *hash=
nil;
NSMutableString* output = [NSMutableStringstringWithCapacity:CC_SHA256_DIGEST_LENGTH
*2];
for(int i =0; i <
CC_SHA256_DIGEST_LENGTH; i++){
[output appendFormat:@"%02x", cHMAC[i]];
}
hash = output;
return hash;
}
3. 配置文件。其中商户秘钥是不正确的。
// ApplePayCommont.h
// Apple_Pay
//
// Created by 周双建 on 16/2/25.
// Copyright © 2016年周双建. All rights reserved.
//
#ifndef ApplePayCommont_h
#define ApplePayCommont_h
//// 商户号
static NSString *kLLOidPartner =@"201602190000022156";
// 商户秘钥
static NSString *kLLPartnerKey =@"201601250000011007";//这个不匹配,切记
NSString *kAPMerchantID =@"merchant.com.zsj.ApplePay";
#endif /* ApplePayCommont_h */
4.订单的创建。
#pragma mark 创建订单
-(void)CreateOrderInfo{
//
获取当前时间
NSDateFormatter * DateFormatter = [[NSDateFormatteralloc]init];
[DateFormatter setDateFormat:@"yyyyMMddHHmmss"];
// 将时间转化成字符串
NSString * PresentTimeString = [DateFormatterstringFromDate:[NSDatedate]];
//
订单前的标志
NSString * OrderPresentSign =
@"LL";
//
加密的形式 MD5 RSA
哈希
NSString * SignType =
@"MD5";
// 声明一个可变的参数字典
self.OrderInfoMutableDict = [NSMutableDictionarydictionaryWithCapacity:0];
NSMutableDictionary * PrameMutableDict = [NSMutableDictionarydictionary];
[PrameMutableDict setDictionary:@{
//签名方式String
RSA 或者 MD5
@"sign_type":SignType,
//商户业务类型是String(6)虚拟商品销售:101001
@"busi_partner":@"101001",
//商户订单时间dt_order是String(14)格式:YYYYMMDDH24MISS
14位数字,精确到秒
@"dt_order":PresentTimeString,
//交易金额money_order
是Number(8,2)
该笔订单的资金总额,单位为RMB-元。大于0的数字,精确到小数点后两位。如:49.65
@"money_order":@"0.10",
//服务器异步通知地址notify_url
是String(64)
连连钱包支付平台在用户支付成功后通知商户服务端的地址。
@"notify_url":@"http://test.yintong.com.cn:80/apidemo/API_DEMO/notifyUrl.htm",
//商户唯一订单号no_order
是String(32)
商户系统唯一订单号
@"no_order":[NSStringstringWithFormat:@"%@%@",OrderPresentSign,PresentTimeString],
//商品名称name_goods
否String(40)
@"name_goods":@"琴女的皮肤",
//订单附加信息info_order
否String(255)
商户订单的备注信息,还可以详细描述。
@"info_order":PresentTimeString,
//分钟为单位,默认为10080分钟(7天),从创建时间开始,过了此订单有效时间此笔订单就会被设置为失败状态不能再重新进行支付。
@"valid_order":@"10080",
//@"shareing_data":@"201412030000035903^101001^10^分账说明1|201310102000003524^101001^11^分账说明2|201307232000003510^109001^12^分账说明3"
//
分账信息数据 shareing_data
否 变(1024)
//@"risk_item":@"{\"user_info_bind_phone\":\"13958069593\",\"user_info_dt_register\":\"20131030122130\"}",
//风险控制参数否
此字段填写风控参数,采用json串的模式传入,字段名和字段内容彼此对应好
//商户用户唯一编号否
该用户在商户系统中的唯一编号,要求是该编号在商户系统中唯一标识该用户
// user_id,一个user_id标示一个用户
// user_id为必传项,需要关联商户里的用户编号,一个user_id下的所有支付银行卡,身份证必须相同
// demo中需要开发测试自己填入user_id,可以先用自己的手机号作为标示,正式上线请使用商户内的用户编号
@"risk_item" : [ApplePayAlgorithmGetString:@{@"user_info_dt_register":@"20131030122130",@"cinema_name":@"大电影院",@"book_phone":@"18811520397"}],@"user_id":@"xu20160215",
@"oid_partner":kLLOidPartner
}];
self.OrderInfoMutableDict = PrameMutableDict;
// matech ID
预支付AP ID
self.OrderInfoMutableDict[@"ap_merchant_id"] =kAPMerchantID;
if (kLLOidPartner.length >0) {
// 商户秘钥
self.OrderInfoMutableDict[@"oid_partner"] =kLLOidPartner;
return;
}
}
5.Pay支付代码。
// 进行支付
- (void)payWithSignedOrder:(NSDictionary*)signedOrder
{
[LLAPPaySDK
sharedSdk].sdkDelegate =self;
[[LLAPPaySDKsharedSdk]
payWithTraderInfo:signedOrder
inViewController:self];
}
6.Auth 授权。
#pragma mark 预授权
- (void)authWithSignedOrder:(NSDictionary*)signedOrder{
[LLAPPaySDK
sharedSdk].sdkDelegate =self;
[[LLAPPaySDKsharedSdk]
preauthWithTraderInfo:signedOrder
inViewController:self];
}
7.支付的回调。
#pragma mark 支付结果的返回
/* kLLPayResultSuccess = 0, //
支付成功
kLLPayResultFail = 1, //
支付失败
kLLPayResultCancel = 2, //
支付取消,用户行为
kLLPayResultInitError, //
支付初始化错误,订单信息有误,签名失败等
kLLPayResultInitParamError, //
支付订单参数有误,无法进行初始化,未传必要信息等
kLLPayResultUnknow, //
其他
*/
- (void)paymentEnd:(LLPayResult)resultCode withResultDic:(NSDictionary*)dic{
[selfalertView:[ApplePayAlgorithmGetString:dic]];
switch (resultCode) {
casekLLPayResultSuccess:{
// 支付成功
NSString* result_pay = dic[@"result_pay"];
if ([result_pay
isEqualToString:@"SUCCESS"])
{
[self
alertView:@"SUCCESS"];
}
else if ([result_payisEqualToString:@"PROCESSING"])
{
//@"支付单处理中";
[self
alertView:@"支付单处理中"];
}
else if ([result_payisEqualToString:@"FAILURE"])
{
// @"支付单失败";
[self
alertView:@"支付单失败"];
}
else if ([result_payisEqualToString:@"REFUND"])
{
// @"支付单已退款";
[self
alertView:@"支付单已退款"];
}
}
break;
casekLLPayResultFail:{
// 支付失败
[self alertView:@"支付失败"];
}
break;
casekLLPayResultCancel:{
// 用户取消支付
[self
alertView:@"用户取消支付"];
}
break;
casekLLPayResultInitError:{
[selfalertView:@"支付初始化错误,订单信息有误,签名失败等"];
//支付初始化错误,订单信息有误,签名失败等
}
break;
casekLLPayResultInitParamError:{
[selfalertView:@"支付订单参数有误,无法进行初始化,未传必要信息等"];
}
break;
casekLLPayResultUnknow:{
//其他
[self
alertView:@"其他"];
}
break;
default:
break;
}
}
8.切记,不要忘记添加代理。
LLPaySdkDelegate
9.下载地址。
https://github.com/zhoushuangjian/Apple_Pay.git
相关文章推荐
- Ruby on Rails在Ping ++ 平台实现支付
- 微信小程序-详解微信登陆、微信支付、模板消息
- 微信公众号支付(一)如何获取用户openId
- php银联网页支付实现方法
- php微信支付之APP支付方法
- 微信支付开发教程(一)微信支付URL配置
- Android支付宝支付设计开发
- Android调用微信登陆、分享、支付
- 第三方支付接口搜集(附下载)
- 支付金额对不上,找零时刻,货币运算
- 深圳罗湖区政府采购“网上商城”引入第三方比价功能
- 支付架构图
- 支付宝处理结果异常
- 关于微信支付IWXAPIEventHandler接口中onresp不能调用的问题
- 【纯干货】微信支付接入攻略—JAVA代码分享
- 中国移动应用内计费平台服务器接收通知接口示例代码
- 实现微信App支付---关于Android实现App支付时的注意事项(或者叫坑)
- 百度钱包新用户体验,送10元现金
- 解决工行MasterCard安全证书错误
- 思路问题,需要深刻反省