微信支付,我大部分参考的是在 code4app找的demo。感谢作者。http://www.code4app.com/ios/支付宝和微信支付两种方式集成/568e1c0fb5ad2e73288b4c0f
有很多可能多余的步骤。
参考微信官方文档https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=1417694084&token=&lang=zh_CN
1 先下载 微信SDK。放在一个文件夹下,然后拖进工程里。在 Build Phases加上所需要的系统库,SystemConfiguration.framework,libz.dylib,libsqlite3.0.dylib,libc++.dylib。
2 在Xcode中,选择你的工程设置项,选中“TARGETS”一栏,在“info”标签栏的“URL type“添加“URL scheme”为你所注册的应用程序id(就是申请的 APP ID)
3 开始支付
1)在AppDlegate 里面注册你的应用。在你需要使 用微信终端API的文件中import WXApi.h 头文件,并增加 WXApiDelegate 协议。
[WXApiregisterApp:@"wx××××××××××××××××"withDescription:@"YourApp"];
2)重写AppDelegate的handleOpenURL和openURL方法:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
return [WXApihandleOpenURL:urldelegate:self];
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
if ([url.hostisEqualToString:@"safepay"]) {
[[AlipaySDKdefaultService]processOrderWithPaymentResult:urlstandbyCallback:^(NSDictionary *resultDic) {
//这是支付宝支付。因为私钥错误没写
}];
}
else
{
return [WXApihandleOpenURL:urldelegate:self];
}
return YES;
}
3)微信支付 然后按照 demo上来就可以调起微信客户端支付了(下面摘自demo)
①、统一下单
https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=9_1 ->API列表->统一下单 按照文档要求appid,mch_id,nonce_str,sign,body,out_trade_no,total_fee,spbill_create_ip,notify_url,trade_type这十个参数是必须的。
其中appid,mch_id是微信给的;trade_type传定值APP;nonce_str,spbill_create_ip是直接在手机上获取到的;body,out_trade_no,total_fee这三个是从服务端上获取的数据。sign根据以上键值对按照签名规则得到的。
out_trade_no这个是32位随机,老是没有成功是因为项目中后台生成订单号不符合。total_fee这个是按照 “分”做单位的
完成之后要转化成XML格式上传到微信服务器。
第一个比较坑的地方在这,如果直接使用AF的POST方式是不行的,总是会返回"XML格式错误"。必须使用NSMutableURLRequest添加method和body,然后用AFHTTPRequestOperation进行网络请求才行。
然后接收到数据的返回。其中返回数据中有用的只有prepayid,其他的要么本地就有,要么就是恶心你的值。
② 客户端调起支付
https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=9_1 ->API列表->调起支付接口 文档要求appid,partnerid,prepayid,package,noncestr,timestamp,sign这七个参数是必须的,但是DEMO中appid根本没有用到,所以其实只需要六个参数,这是第二个坑爹的地方!!! partnerid就是第一步的mch_id,prepayid是上一步返回的最重要的数据,package传定值Sign=WXPay,noncestr就是上一步中的nonce_str,timestamp这个按照规则生成十位的。
sign是最最最坑的地方,不是上一步返回的那个sign,不是上一步返回的那个sign,不是上一步返回的那个sign。他是根据上面的五个参数进行签名得出的值。不然每次调用就只看见微信界面只有一个确定。
对于返回签名错误的,可以对照他们的签名测试工具检验。https://pay.weixin.qq.com/wiki/tools/signverify/
4)支付结果
⑴(使用的不安全的 客户端直接向微信服务器查询,)在AppDelegate中
-(void)onResp:(BaseResp *)resp
{
/*
ErrCode ERR_OK = 0(用户同意)
ERR_AUTH_DENIED = -4(用户拒绝授权)
ERR_USER_CANCEL = -2(用户取消)
code 用户换取access_token的code,仅在ErrCode为0时有效
state 第三方程序发送时用来标识其请求的唯一性的标志,由第三方程序调用sendReq时传入,由微信终端回传,state字符串长度不能超过1K
lang 微信客户端当前语言
country 微信用户当前国家信息
*/
NSString *strMsg = [NSStringstringWithFormat:@"errcode:%d", resp.errCode];
NSString *strTitle;
if([resp isKindOfClass:[PayRespclass]]){
//支付返回结果,实际支付结果需要去微信服务器端查询
strTitle = [NSString stringWithFormat:@"支付结果"];
[[NSNotificationCenterdefaultCenter]postNotificationName:WEIXINPAYobject:resp];
//然后在你需要的地方接收通知.
}
}
- (void)payWeiX:(NSNotification *)noti{
if (noti) {
PayResp * resp = noti.object;
NSString * strMsg;
switch (resp.errCode) {
case WXSuccess:
strMsg = @"支付结果:成功!";
NSLog(@"支付成功-PaySuccess,retcode = %d", resp.errCode);
break;
caseWXErrCodeUserCancel:
strMsg = @"交易取消";
break;
default:
strMsg = [NSString stringWithFormat:@"支付结果:失败!retcode = %d, retstr = %@", resp.errCode,resp.errStr];
NSLog(@"错误,retcode = %d, retstr = %@", resp.errCode,resp.errStr);
break;
}
[ZRDUtilyHUDShowMessage:strMsgaddedToView:self.view];
}
}
最后,就是这些了。