IOS中微信支、支付宝支付详解

1. 项目中遇到了微信支付和支付宝支付,现贡献详细代码,具体的参数在代码中都有详细的备注:

  9 #import "ITMPay.h"
 10 #import "WXApi.h"
 11 #import <AlipaySDK/AlipaySDK.h>
 12 #import "Order.h"//
 13 #import "DataSigner.h"//
 14 #import "XMLDictionary.h"//xml解析转换
 15 #import "DataMD5.h"//MD5 加密
 16 
 17 #pragma mark - 微信
 18 #define WXAppId    @""  //appId,申请微信账号时获取的
 19 #define WXAppSecret @"" //appSecret 申请app账号时获取
 20 #define WXShangHu @""   //申请成功后获取的商户号
 21 #define WXMiYue @""     //申请成功后获取的商户密钥
 22 
 23 #pragma mark - 支付宝
 24 #define AliShanghuId @""   //申请成功后获取的商户ID
 25 #define AliShanghuUser @"" //商户支付宝账号
 26 #define AliShanghuMiyue @""//申请成功后获取的商户密钥(私钥)
 27 
 28 @implementation ITMPay
 29 
 30 +(void)payWithType:(OrderPayType)type andDic:(NSMutableDictionary *)dic{
 31     if (type == OrderPayTypeAliy) {
 32         [self payWithAliPay:dic];
 33     }else if (type == OrderPayTypeWeixin){
 34         [self payWithWXWith:dic];
 35     }
 36 }
 37 
 38 #pragma mark -
 39 #pragma mark 支付宝支付
 40 /** 
 41     支付宝的支付步骤
 42  *  1. 根据传入的字典获取生成相应的Order,生成[order description]
 43  *  2. 根据私钥生成签名器:signer,并将生成的[order description]签名
 44  *  3. 根据1、2中生成的结果,做为orderString
 45  *  4. 将orderString,和appScheme(此处可以任意字符串)做为参数,调用[AlipaySDK defaultService] payOrder:fromScheme: callback 进行支付
 46  */
 47 + (void)payWithAliPay:(NSMutableDictionary *)dic{
 48     NSString *partner = AliShanghuId;
 49     NSString *seller = AliShanghuUser;
 50     NSString *privateKey = AliShanghuMiyue;
 51     
 52     Order *order = [[Order alloc] init];
 53     order.partner = partner;
 54     order.seller = seller;
 55     
 56     order.tradeNO = dic[@"order_id"]; //订单ID(由商家自行制定)
 57     order.productName = dic[@"order_title"]; //商品标题
 58     order.productDescription = dic[@"order_desc"]; //商品描述
 59     order.amount = dic[@"order_price"]; //商品价格
 60     
 61     order.service = @"mobile.securitypay.pay";//支付宝支付服务器名称
 62     order.paymentType = @"1";
 63     order.inputCharset = @"utf-8";
 64     order.itBPay = @"30m";
 65     order.showUrl = @"m.alipay.com";
 66     
 67     NSString *appScheme = @"alisdkdemo";
 68     NSString *orderSpec = [order description];
 69     NSLog(@"orderSpec = %@",orderSpec);
 70     
 71     //获取私钥并将商户信息签名,外部商户可以根据情况存放私钥和签名,只需要遵循RSA签名规范,并将签名字符串base64编码和UrlEncode
 72     id<DataSigner> signer = CreateRSADataSigner(privateKey);
 73     NSString *signedString = [signer signString:orderSpec];
 74     
 75     //将签名成功字符串格式化为订单字符串,请严格按照该格式
 76     NSString *orderString = nil;
 77     if (signedString != nil) {
 78         orderString = [NSString stringWithFormat:@"%@&sign=\"%@\"&sign_type=\"%@\"",
 79                        orderSpec, signedString, @"RSA"];
 80 
 81         [[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
 82             
 83             UIAlertView *aler = [[UIAlertView alloc]initWithTitle:@"提示" message:[resultDic[@"resultStatus"] isEqualToString:@"9000"]? @"交易成功":@"交易失败" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles: nil];
 84             [aler show];
 85         }];
 86         
 87     }
 88 }
 89 /**
 90  *  和支付宝支付相比,微信支付步骤要复杂些
 91  *  1. 配置传入字典的各种参数
 92  *  2. 将配置完的字典签名生成sign,并且将这个sign做为传入字典的sign值
 93  *  3. 再次将这个dic转换成XML的格式
 94  *  4. 将生成的XML格式的字符串做为参数访问微信接口
 95  *  5. 将微信服务器返回值,做为sendReq的的Value
 96  *  6. 将sendReq.sign进行MD5加密,
 97  */
 98 
 99 #pragma mark 微信支付
100 + (void)payWithWXWith:(NSMutableDictionary *)dic{
101     [dic setValue:WXAppId forKey:@"appid"];   //APPid
102     [dic setValue:WXShangHu forKey:@"mch_id"];//商户号Id
103     [dic setValue:@"APP" forKey:@"trade_type"];//交易类型
104     
105     int value = arc4random();
106     [dic setValue:[NSString stringWithFormat:@"%d",value] forKey:@"nonce_str"];//随机字符串
107     
108     [dic setValue:@"http://10.2.10.122/itm_app/payReturnContrller/Paymentcompletion.htmls" forKey:@"notify_url"];//回调地址
109     
110     [dic setValue:@"111.204.81.66" forKey:@"spbill_create_ip"];//终端IP
111     
112     //获取签名
113     NSString *sign = [self signWithDic:dic];
114     [dic setValue:sign forKey:@"sign"];//签名
115     NSString *xml = [dic XMLString];//把签名转成xml格式
116     [self httpWithXml:xml];
117 }
118 
119 #pragma mark -
120 #pragma mark 调用微信支付
121 + (void)httpWithXml:(NSString *)xml{
122     AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
123     
124     //这里传入的xml字符串只是形似xml,但是不是正确是xml格式,需要使用af方法进行转义
125     manager.responseSerializer = [[AFHTTPResponseSerializer alloc] init];
126     [manager.requestSerializer setValue:@"text/xml; charset=GBK" forHTTPHeaderField:@"Content-Type"];
127     [manager.requestSerializer setValue:@"https://api.mch.weixin.qq.com/pay/unifiedorder" forHTTPHeaderField:@"SOAPAction"];
128     
129     [manager.requestSerializer setQueryStringSerializationWithBlock:^NSString *(NSURLRequest *request, NSDictionary *parameters, NSError *__autoreleasing *error) {
130         return xml;
131     }];
132     //发起请求
133     [manager POST:@"https://api.mch.weixin.qq.com/pay/unifiedorder" parameters:xml success:^(AFHTTPRequestOperation *operation, id responseObject) {
134         NSString *responseString = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding] ;
135         NSLog(@"responseString is %@",responseString);
136         //将微信返回的xml数据解析转义成字典
137         NSDictionary *dic = [NSDictionary dictionaryWithXMLString:responseString];
138         //判断返回的许可
139         if ([[dic objectForKey:@"result_code"] isEqualToString:@"SUCCESS"] &&[[dic objectForKey:@"return_code"] isEqualToString:@"SUCCESS"] ) {
140             
141             //发起微信支付,设置参数
142             PayReq *request = [[PayReq alloc] init];
143             request.partnerId = [dic objectForKey:@"mch_id"];
144             request.prepayId= [dic objectForKey:@"prepay_id"];
145             request.package = @"Sign=WXPay";
146             request.nonceStr= [dic objectForKey:@"nonce_str"];
147             
148             //将当前事件转化成时间戳
149             NSDate *datenow = [NSDate date];
150             NSString *timeSp = [NSString stringWithFormat:@"%ld", (long)[datenow timeIntervalSince1970]];
151             UInt32 timeStamp =[timeSp intValue];
152             request.timeStamp= timeStamp;
153             
154             //二次签名
155             DataMD5 *md5 = [[DataMD5 alloc] init];
156             request.sign=[md5 createMD5SingForPay:WXAppId partnerid:request.partnerId prepayid:request.prepayId package:request.package noncestr:request.nonceStr timestamp:request.timeStamp];
157             // 调用微信
158             [WXApi sendReq:request];
159             
160         }else{
161             NSLog(@"参数不正确,请检查参数");
162         }
163         
164     } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
165         NSLog(@"error is %@",error);
166     }];
167 
168 }
169 #pragma mark 设置签名
170 + (NSString *)signWithDic:(NSDictionary *)dict{
171       NSMutableString *contentString  =[NSMutableString string];
172 
173      NSArray *keys = [dict allKeys];
174 //     按字母顺序排序
175      NSArray *sortedArray = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
176      return [obj1 compare:obj2 options:NSNumericSearch];
177      }];
178 
179      for (NSString *categoryId in sortedArray) {
180      if (   ![[dict objectForKey:categoryId] isEqualToString:@""]
181      && ![categoryId isEqualToString:@"sign"]
182      && ![categoryId isEqualToString:@"key"]
183      )
184      {
185      [contentString appendFormat:@"%@=%@&", categoryId, [dict objectForKey:categoryId]];
186      }
187     
188      }
189 //   添加key字段
190      [contentString appendFormat:@"key=%@",WXMiYue ];
191      NSDLog(@"qianming:%@",contentString);
192      
193      DataMD5 *md5Sign = [[DataMD5 alloc]initWithAppid:dict[@"appid"] mch_id:dict[@"mch_id"] nonce_str:dict[@"nonce_str"] partner_id:WXMiYue body:dict[@"body"] out_trade_no:dict[@"out_trade_no"] total_fee:dict[@"total_fee"] spbill_create_ip:dict[@"spbill_create_ip"] notify_url:dict[@"notify_url"] trade_type:dict[@"trade_type"]];
194      NSString *md5Sign1 =[md5Sign getSignForMD5];
195      
196      return md5Sign1;
197 }
198 
199 @end

 

posted @ 2016-01-12 19:38  击水湘江  阅读(890)  评论(1编辑  收藏  举报