微信支付流程
官方说明
https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=8_5
环境设置
拖入我附件中的SDK(可以将我附件中的SDK替换为官方的, 只为你放心)
-
设置URL Schemes : 微信应用注册后的 : AppID
3 . 需要导入的框架
libc++.tbd libz.tbd libsqlite3.0.tbd SystemConfiguration.framework CoreTelephony.framework
4 . 为了以防万一 : 备用
// 设置URLSchemes白名单
LSApplicationQueriesSchemes
weixin
//设置退回Http
NSAppTransportSecurity
NSAllowsArbitraryLoads
AppDelegate中
#import "WXApi.h"
@interface AppDelegate ()
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[WXApi registerApp:AppID withDescription:@"demo 2.0"];
return YES;
}
//微信支付返回程序
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
return [WXApi handleOpenURL:url delegate:self];
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
return [WXApi handleOpenURL:url delegate:self];
}
// 并且将下面方法添加到上面设置的delegate中, 支付完成微信会回调代理的这个方法
- (void)onResp:(BaseResp*)resp{
if ([resp isKindOfClass:[PayResp class]]){
PayResp *response = (PayResp*)resp;
switch(response.errCode){
case WXSuccess:
//服务器端查询支付通知或查询API返回的结果再提示成功
NSLog(@"支付成功");
break;
default:
NSLog(@"支付失败,retcode=%d",resp.errCode);
break;
}
}
}
// 使用CCPay, 修改自己需要的即可
CCPay中封装的代码 主要流程
一. 预支付 : 发送商品信息到预支付地址获取prepay_id
- 收集预付单参数
参数 noncestr 与 orderno 都是随机生成的
[orderParas setObject: CCAppID forKey:@"appid"]; //开放平台appid
[orderParas setObject: CCMchID forKey:@"mch_id"]; //商户号
[orderParas setObject: @"iPhone10X" forKey:@"device_info"]; //支付设备号或门店号
[orderParas setObject: noncestr forKey:@"nonce_str"]; //随机串
[orderParas setObject: @"APP" forKey:@"trade_type"]; //支付类型,固定为APP
[orderParas setObject: @"大宝SOD咪咪" forKey:@"body"]; //订单描述,展示给用户
[orderParas setObject: @"You_Custom" forKey:@"notify_url"]; //支付结果异步通知
[orderParas setObject: orderno forKey:@"out_trade_no"];//商户订单号
[orderParas setObject: [CCDevice deviceIPAdress] forKey:@"spbill_create_ip"];//发起支付的机器ip
[orderParas setObject: @"1" forKey:@"total_fee"]; //订单金额,单位为分
- 通过上面的参数按照官方的要求生成XML格式的参数
NSMutableString *reqPars = [NSMutableString string];
//生成xml的package
NSArray *keys = [paras allKeys];
[reqPars appendString:@"\n"];
for (NSString *categoryId in keys) {
[reqPars appendFormat:@"<%@>%@%@>\n", categoryId, [paras objectForKey:categoryId],categoryId];
}
//生成签名,并将签名添加到签名包中
sign = [self createMd5Sign:paras];
[reqPars appendFormat:@"%@ \n ", sign];
return [NSString stringWithString:reqPars];
- 将该参数转换为Data数据,通过POST发出请求
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:5];
//设置提交方式
[request setHTTPMethod:method];
//设置数据类型
[request addValue:@"text/xml" forHTTPHeaderField:@"Content-Type"];
//设置编码
[request setValue:@"UTF-8" forHTTPHeaderField:@"charset"];
//如果是POST
[request setHTTPBody:[data dataUsingEncoding:NSUTF8StringEncoding]];
NSError *error;
//将请求的url数据放到NSData对象中
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];
return response;
- 解析响应的NSData数据, 获得prepayid
dictionary =[NSMutableDictionary dictionary];
contentString=[NSMutableString string];
// XML解析实例
xmlElements = [[NSMutableArray alloc] init];
xmlParser = [[NSXMLParser alloc] initWithData:data];
[xmlParser setDelegate:self];
[xmlParser parse];
代理中得到数据, 获取 prepayid
二. 真正的支付 : 发送PayReq(官方类)请求
- 生成确认支付的参数
//获取到prepayid后进行第二次签名
//设置支付参数
time_t now;
time(&now);
NSString *time_stamp = [NSString stringWithFormat:@"%ld", now];
NSString *nonce_str = [CCUtil stringMd5WithString:time_stamp];
NSString *package = @"Sign=WXPay"; // 官方要求
// 第二次签名参数列表
NSMutableDictionary *signParas = [NSMutableDictionary dictionary];
[signParas setObject: CCAppID forKey:@"appid"];
[signParas setObject: nonce_str forKey:@"noncestr"];
[signParas setObject: package forKey:@"package"];
[signParas setObject: CCMchID forKey:@"partnerid"];
[signParas setObject: time_stamp forKey:@"timestamp"];
[signParas setObject: prepayID forKey:@"prepayid"];
//[signParams setObject: @"MD5" forKey:@"signType"];
// 生成签名
NSString *sign = [self createMd5Sign:signParas];
// 添加签名
[signParas setObject: sign forKey:@"sign"];
return signParas;
- 调用微信进行支付
PayReq* req = [[PayReq alloc] init];
req.openID = [paras objectForKey:@"appid"];
req.partnerId = [paras objectForKey:@"partnerid"];
req.prepayId = [paras objectForKey:@"prepayid"];
req.nonceStr = [paras objectForKey:@"noncestr"];
req.timeStamp = [[paras objectForKey:@"timestamp"] intValue];
req.package = [paras objectForKey:@"package"];
req.sign = [paras objectForKey:@"sign"];
// 发起微信支付
[WXApi sendReq:req];
代码
http://pan.baidu.com/s/1qXt463y
封装为传入参数 : 订单名与价格即可开始支付, 有自己的需求, 到.m中自行修改
/**
* 通过微信支付
*
* @param orderName 订单名
* @param price 价格
*/
+ (void)payWXWithOrderName:(NSString *)orderName price:(NSString *)price;
最后
上面流程为自己从头开始完成支付, 并不是说必须按照上面步骤. 这里不同公司可能如何处理方式会有差异.
例如: 第一步预支付验证可以后台实现, 前台只需要请求公司内部服务器, 内部服务器发送对应的预支付请求, 并且将返回的数据简析完成后返回给前台, 前台直接执行支付操作.