1.支付宝集成
第一步:先签约支付宝,申请应用(别忘了生成的 RSA 密钥的上传)
https://doc.open.alipay.com/doc2/detail.htm?spm=0.0.0.0.6i3qlX&treeId=58&articleId=103542&docType=1
第二步:下载支付宝官方的 SDK, 把第一步申请得到的 sellID,partnerID,私钥(privateKey)放到代码中,为了测试我们配置的 key 是否正确,如果支付宝 demo 能支付成功,就代表我们配置的 key 成功了,反之去重复第一步吧
L:148
NSString *partner = @"xxxxxxx";
NSString *seller = @"xxxxxxx";
NSString *privateKey = @"xxxxxxx" ;//注意空格!!
第三步:配置支付宝到 app
1>配置库,看支付宝官方的就好,比哪都详细
https://doc.open.alipay.com/doc2/detail.htm?spm=0.0.0.0.l0wbHb&treeId=59&articleId=103676&docType=1
但要注意: "Header Search Paths”增加头文件路径:$(SRCROOT)/项目名称!!!!
还有记得设置回调
2>把下图的文件从支付宝官方 demo 中拷贝过来
编译,如果有报错,缺库就导库,头文件就 header search paths,
我还需要一个报错,导了一个 demo 里没有的库:libstdc++.6.0.9. tbd
3>处理支付的商品信息,签名等等
导入头文件
#import "Order.h"
#import <AlipaySDK/AlipaySDK.h>
#import "DataSigner.h"
处理支付业务
/**
* 1.生成订单信息
*/
Order *order = [[Order alloc]init];
order.partner = PARTNER;
order.seller = SELLER;
order.tradeNO = self.orderCode;
order.productName = @"这是一个支付宝测试";
order.productDescription = @"我说了这是一个测试数据";
order.amount = [NSString stringWithFormat:@"%.2f",0.01];
//回调 URL
order.notifyURL = @"url url url ";
order.service = @"mobile.securitypay.pay";
order.paymentType = @"1";
order.inputCharset = @"utf-8";
order.itBPay = @"30m";
order.showUrl = @"m.alipay.com";
// 应用注册scheme,在当前项目的Info.plist定义URL types
NSString *appScheme = @"";//同 url types
//将订单信息拼接成在字符串
NSString *orderSpec = [order description];
第一步基本上和官方 demo 一样,比微信好多了(不得不吐槽一下)
/**
* 2.签名加密
* 获取私钥并将商户信息签名, 外部商户可以根据情况存放私钥和签名, 只需要遵循 RSA 签名规范, 并将签名字符串 base64 编码和 UrlEncode
*/
NSString *str = PRIVATE;
id<DataSigner> signer = CreateRSADataSigner(str);
NSString *signedString = [signer signString:orderSpec];
请直接copy demo 这一部分
/**
* 3. 将签名成功字符串格式化为订单字符串,请严格按照该格式
*/
NSString *orderString = nil;
if (signedString != nil) {
orderString = [NSString stringWithFormat:@"%@&sign=\"%@\"&sign_type=\"%@\"",
orderSpec, signedString, @"RSA"];
[[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
//处理你的支付结果
NSLog(@"resuly===%@",resultDic);
}
}];
}
appDelegate里面需要设置
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
/**
* Alipay
*/
//如果极简开发包不可用,会跳转支付宝钱包进行支付,需要将支付宝钱包的支付结果回传给开 发包
if ([url.host isEqualToString:@"safepay"]) {
[[AlipaySDK defaultService]processOrderWithPaymentResult:url
standbyCallback:^(NSDictionary *resultDic) {
#warning ======支付结果处理
NSLog(@"ewsult====%@",resultDic);
}];
}
//支付宝钱包快登授权返回
if ([url.host isEqualToString:@"platformapi"]) {
[[AlipaySDK defaultService]processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
#warning ======支付结果处理
NSLog(@"ewsult====%@",resultDic);
}];
}
}
支付宝就这么多了,很简单的代码,一般的配置,复杂的申请....
2.微信支付
做微信支付是有挺多小坑的,这个坑主要取决于你的后台怎么样,微信不同于支付宝的是,它把支付过程分成了两步,就到导致了后台需要先做第一步,再传数据给前端,然后前端去完成第二步.
第一步是:向微信注册你的应用程序 ID
这一步没什么技术,按照流程就好了(这都是产品经理做的吧.....)
https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317780&token=f6e95c1f1c5fd970d5fb3b2425e2d612b6cbce47&lang=zh_CN
照这个流程来就好
第二步:下载官方 demo
https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=11_1
其实不推荐官方的 demo...而且微信的官方 demo 不像支付宝一样还可以用来去检查 appId,等等值是否配好
第三步:配置微信 SDK
需要配置的库好像跟支付宝差不多...
第四步:调用微信支付 SDK
这个第四步就要分情况讨论了
微信的支付流程是先获取prePayid,再加appid,appkey,noncestr,package,partnerId,timestamp去签名完成支付.
第一种情况:如果你的后台去完成获取预支付订单
这种是微信支付官方推荐的,而且这样更加安全,相关的配置信息和 key 都存在服务器更加安全.
这种情况前端需要在用户发起微信支付后吧订单信息传给服务器(传递的信息需要沟通),返回值为
// 调起微信支付
PayReq *request = [[PayReq alloc]init];
request.partnerId = _WXPayModel.partnerid;
request.prepayId = _WXPayModel.prepayid;
request.package = @"Sign=WXPay";
request.nonceStr = _WXPayModel.noncestr;
request.timeStamp = [_WXPayModel.timestamp intValue];
package 一定要写成那样!
package 一定要写成那样!
package 一定要写成那样!
// 这里要注意key里的值一定要填对, 微信官方给的参数名是错误的,不是第二个字母大写
NSMutableDictionary *signParams = [NSMutableDictionary dictionary];
[signParams setObject: _WXPayModel.appid forKey:@"appid"];
[signParams setObject: _WXPayModel.partnerid forKey:@"partnerid"];
[signParams setObject: request.nonceStr forKey:@"noncestr"];
[signParams setObject: request.package forKey:@"package"];
[signParams setObject: _WXPayModel.timestamp forKey:@"timestamp"];
[signParams setObject: request.prepayId forKey:@"prepayid"];
//生成签名
NSString *sign = [MyUtil genSign:signParams];
NSLog(@"sign===%@",sign);
//添加签名
request.sign = sign;
[WXApi sendReq:request];
基本上调起支付的代码就这样...这当然是在服务端完成第一步的情况下.
第二种情况:(如果你家后台又懒又不会而且你又比较闲的话)
//微信支付
- (void)wxpay
{
//商户号
NSString *PARTNER_ID = @"1900000109";
//商户密钥
NSString *PARTNER_KEY = @"8934e7d15453e97507ef794cf7b0519d";
//APPID
NSString *APPI_ID = @"wxd930ea5d5a258f4f";
//appsecret
NSString *APP_SECRET = @"db426a9829e4b49a0dcac7b4162da6b6";
//支付密钥
NSString *APP_KEY = @"L8LrMqqeGRxST5reouB0K66CaYAWpqhAVsq7ggKkxHCOastWksvuX1uvmvQclxaHoYd3ElNBrNO2DHnnzgfVG9Qs473M3DTOZug5er46FhuGofumV8H2FVR9qkjSlC5K";
NSLog(@"%ld,%ld,%ld",PARTNER_KEY.length,APP_SECRET.length,APP_KEY.length);
//支付结果回调页面
NSString *NOTIFY_URL = @"http://localhost/pay/wx/notify_url.asp";
//订单标题
NSString *ORDER_NAME = @"Ios客户端签名支付 测试";
//订单金额,单位(分)
NSString *ORDER_PRICE = @"1";
//创建支付签名对象
payRequsestHandler *req = [payRequsestHandler alloc];
//初始化支付签名对象
[req init:APPI_ID app_secret:APP_SECRET partner_key:PARTNER_KEY app_key:APP_KEY];
//判断Token过期时间,10分钟内不重复获取,测试帐号多个使用,可能造成其他地方获取后不能用,需要即时获取
time_t now;
time(&now);
//if ( (now - token_time) > 0 )//非测试帐号调试请启用该条件判断
{
//获取Token
Token = [req GetToken];
//设置Token有效期为10分钟
token_time = now + 600;
//日志输出
NSLog(@"获取Token: %@\n",[req getDebugifo]);
}
if ( Token != nil){
//================================
//预付单参数订单设置
//================================
NSMutableDictionary *packageParams = [NSMutableDictionary dictionary];
[packageParams setObject: @"WX" forKey:@"bank_type"];
[packageParams setObject: ORDER_NAME forKey:@"body"];
[packageParams setObject: @"1" forKey:@"fee_type"];
[packageParams setObject: @"UTF-8" forKey:@"input_charset"];
[packageParams setObject: NOTIFY_URL forKey:@"notify_url"];
[packageParams setObject: [NSString stringWithFormat:@"%ld",time(0)] forKey:@"out_trade_no"];
[packageParams setObject: PARTNER_ID forKey:@"partner"];
[packageParams setObject: @"196.168.1.1" forKey:@"spbill_create_ip"];
[packageParams setObject: ORDER_PRICE forKey:@"total_fee"];
NSString *package, *time_stamp, *nonce_str, *traceid;
//获取package包
package = [req genPackage:packageParams];
//输出debug info
NSString *debug = [req getDebugifo];
NSLog(@"gen package: %@\n",package);
NSLog(@"生成package: %@\n",debug);
//设置支付参数
time_stamp = [NSString stringWithFormat:@"%ld", now];
nonce_str = [TenpayUtil md5:time_stamp];
traceid = @"mytestid_001";
NSMutableDictionary *prePayParams = [NSMutableDictionary dictionary];
[prePayParams setObject: APPI_ID forKey:@"appid"];
[prePayParams setObject: APP_KEY forKey:@"appkey"];
[prePayParams setObject: nonce_str forKey:@"noncestr"];
[prePayParams setObject: package forKey:@"package"];
[prePayParams setObject: time_stamp forKey:@"timestamp"];
[prePayParams setObject: traceid forKey:@"traceid"];
//生成支付签名
NSString *sign;
sign = [req createSHA1Sign:prePayParams];
//增加非参与签名的额外参数
[prePayParams setObject: @"sha1" forKey:@"sign_method"];
[prePayParams setObject: sign forKey:@"app_signature"];
//获取prepayId
NSString *prePayid;
prePayid = [req sendPrepay:prePayParams];
//输出debug info
debug = [req getDebugifo];
NSLog(@"提交预付单: %@\n",debug);
if ( prePayid != nil) {
//重新按提交格式组包,微信客户端5.0.3以前版本只支持package=Sign=***格式,须考虑升级后支持携带package具体参数的情况
//package = [NSString stringWithFormat:@"Sign=%@",package];
package = @"Sign=WXPay";
//签名参数列表
NSMutableDictionary *signParams = [NSMutableDictionary dictionary];
[signParams setObject: APPI_ID forKey:@"appid"];
[signParams setObject: APP_KEY forKey:@"appkey"];
[signParams setObject: nonce_str forKey:@"noncestr"];
[signParams setObject: package forKey:@"package"];
[signParams setObject: PARTNER_ID forKey:@"partnerid"];
[signParams setObject: time_stamp forKey:@"timestamp"];
[signParams setObject: prePayid forKey:@"prepayid"];
//生成签名
sign = [req createSHA1Sign:signParams];
//输出debug info
debug = [req getDebugifo];
NSLog(@"调起支付签名: %@\n",debug);
//调起微信支付
PayReq* req = [[PayReq alloc] init];
req.openID = APPI_ID;
req.partnerId = PARTNER_ID;
req.prepayId = prePayid;
req.nonceStr = nonce_str;
req.timeStamp = now;
req.package = package;
req.sign = sign;
[WXApi safeSendReq:req];
}else{
/*long errcode = [req getLasterrCode];
if ( errcode == 40001 )
{//Token实效,重新获取
Token = [req GetToken];
token_time = now + 600;
NSLog(@"获取Token: %@\n",[req getDebugifo]);
};*/
NSLog(@"获取prepayid失败\n");
[self alert:@"提示信息" msg:debug];
}
}else{
NSLog(@"获取Token失败\n");
[self alert:@"提示信息" msg:@"获取Token失败"];
}
}
第四步:设置 url回调以及等等琐碎的东西
1.info URL Types 设置app回调
2.appdelegate中注册 app
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
[WXApi registerApp:@"xxxxxxxxxxxx" withDescription:@"xxxxxx"];
微信支付完成后会通过 appdelegate 中的代理方法发送通知,处理支付结果
if ([resp isKindOfClass:[PayResp class]]) {
PayResp *response = (PayResp *)resp;
NSLog(@"response.errCoderesponse.errCoderesponse.errCode%d",response.errCode);
switch (response.errCode) {
case WXSuccess:{
NSLog(@"successWXPay");
NSNotification *notification = [NSNotification notificationWithName:@"orderPay" object:@"success"];
[[NSNotificationCenter defaultCenter]postNotification:notification];
break;
}
case WXErrCodeCommon:
[SVProgressHUD showErrorWithStatus:@"发送错误"];
break;
case WXErrCodeUserCancel:
[SVProgressHUD showErrorWithStatus:@"支付已取消"];
break;
case WXErrCodeSentFail:
[SVProgressHUD showErrorWithStatus:@"发送失败"];
break;
case WXErrCodeUnsupport:
[SVProgressHUD showErrorWithStatus:@"微信不支持"];
break;
// WXErrCodeCommon = -1, /**< 普通错误类型 */
// WXErrCodeUserCancel = -2, /**< 用户点击取消并返回 */
// WXErrCodeSentFail = -3, /**< 发送失败 */
// WXErrCodeAuthDeny = -4, /**< 授权失败 */
// WXErrCodeUnsupport = -5, /**< 微信不支持 */
default:{
NSLog(@"wxpay");
break;
}
}
}
到这里微信支付就差不多完成了,如果出现微信的各种报错,简书上有很多,就不啰嗦了.
再说说做第三方支付的感受吧,其实我以后打算直接用 ping++了.......
网友评论