- 写在前面的话:楼主现在一家小公司任职,公司一直没有招到满意的后台,所以楼主的微信支付所有的逻辑处理全部写在了前端,希望这篇文章能对那些跟楼主处境相似的伙伴们提供点思路。好了,进入正题
- 楼主自己总结的微信支付的基本步骤
- 1、获取订单的基本数据(字典类型的,一般就是订单价格、描述、详情等基础信息)
NSMutableDictionary *packageParams = [NSMutableDictionary dictionary];
[packageParams setObject: APP_ID forKey:@"appid"]; //开放平台appid
[packageParams setObject: MCH_ID forKey:@"mch_id"]; //商户号
[packageParams setObject: @"APP-001" forKey:@"device_info"]; //支付设备号或门店号
[packageParams setObject: noncestr forKey:@"nonce_str"]; //随机串
[packageParams setObject: @"APP" forKey:@"trade_type"]; //支付类型,固定为APP
[packageParams setObject: body forKey:@"body"]; //订单描述,展示给用户
[packageParams setObject: @"www.baidu.com" forKey:@"notify_url"]; //支付结果异步通知
[packageParams setObject: orderID forKey:@"out_trade_no"];//商户订单号
[packageParams setObject: spbill_ip forKey:@"spbill_create_ip"];//发器支付的机器ip
[packageParams setObject: totalFee forKey:@"total_fee"]; // 价格,微信价格单位是分,这点注意和支付宝区分
- 2、将上述基本数据字典,按照key=value的形式转换拼接成字符串
- 3、在第二步的字符串末尾拼接上key(商户API密钥)
- 4、MD5加密第三步生成的字符串,生成的是prePayid(在第五步中签名的作用),字符串类型
- (NSString*)createMd5Sign:(NSMutableDictionary*)dict
{
NSMutableString *contentString =[NSMutableString string];
NSArray *keys = [dict allKeys];
//按字母顺序排序
NSArray *sortedArray = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [obj1 compare:obj2 options:NSNumericSearch];
}];
//拼接字符串
for (NSString *categoryId in sortedArray) {
if (![[dict objectForKey:categoryId] isEqualToString:@""]
&& ![categoryId isEqualToString:@"sign"]
&& ![categoryId isEqualToString:@"key"]
)
{
[contentString appendFormat:@"%@=%@&", categoryId, [dict objectForKey:categoryId]];
}
}
//添加key字段
[contentString appendFormat:@"key=%@", PARTNER_key];
//得到MD5 sign签名
NSString *md5Sign =[NSString stringWithMD5:contentString];
return md5Sign;
}
- 5、由于微信服务器希望我们传给它的是xml格式的数据,所以我们需要把基本的字典数据(第一步中的字典)转换成xml格式,末尾用第四步中的字符串在进行签名,生成新的字符串
- (NSString *)getPackage:(NSMutableDictionary*)packageParams prePayString:(NSString *)sign
{
NSMutableString *reqPars=[NSMutableString string];
//生成xml的package
NSArray *keys = [packageParams allKeys];
[reqPars appendString:@"<xml>\n"];
for (NSString *categoryId in keys) {
[reqPars appendFormat:@"<%@>%@</%@>\n", categoryId, [packageParams objectForKey:categoryId],categoryId];
}
[reqPars appendFormat:@"<sign>%@</sign>\n</xml>", sign];
return [NSString stringWithString:reqPars];
}
- 6、第5步生成的就是预支付订单,用它向微信服务器请求我们需要的订单
NSString *urlStr = @"https://api.mch.weixin.qq.com/pay/unifiedorder";
urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:urlStr];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:5];
request.HTTPMethod = @"POST";
//设置数据类型
[request addValue:@"text/xml" forHTTPHeaderField:@"Content-Type"];
//设置编码
[request setValue:@"UTF-8" forHTTPHeaderField:@"charset"];
//如果是POST
[request setHTTPBody:[orderString dataUsingEncoding:NSUTF8StringEncoding]];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
}];
- 7、将请求下来的数据转成字典数据,这个data就是第6步中的data
NSString *xmlStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSDictionary *dic = [NSDictionary dictionaryWithXMLString:xmlStr];
8、判断
return_code
和``result_code都是成功的,我们再从字典取出
prepay_id`对应的值8、重新拼接生成一个字典属性(里面有7个键值对)大概和上面前3部一样,也是先字典转字符串md5加密,签名
NSString *package, *time_stamp, *nonce_str;
//设置支付参数
time_t now;
time(&now);
time_stamp = [NSString stringWithFormat:@"%ld", now];
nonce_str = [NSString stringWithMD5:time_stamp];
package = @"Sign=WXPay";
//第二次签名参数列表
NSMutableDictionary *signParams = [NSMutableDictionary dictionary];
[signParams setObject: APP_ID forKey:@"appid"];
[signParams setObject: nonce_str forKey:@"noncestr"];
[signParams setObject: package forKey:@"package"];
[signParams setObject: MCH_ID forKey:@"partnerid"];
[signParams setObject: time_stamp forKey:@"timestamp"];
[signParams setObject: prePayid forKey:@"prepayid"];
/**
* 把
*/
NSString *signStr = [self createMd5Sign:signParams];
[signParams setObject:signStr forKey:@"sign"];
- 9、把重新生成的字典传回去
resultblock(signParams, nil);
10、这个字典中就和微信给我们的类中需要的信息一一对应起来了,这样就可以吊起微信支付了
11、最后给个Demo,里面有支付宝和微信两种支付
[我是链接][1]
[1]:https://github.com/liyang123/LYPayDemo.git