zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    定义一个动态的二维数组?
    学习STL map, STL set之数据结构基础
    CMM
    详细解说STL string
    仔细选择你的容器
    C++字符串类string简析
    流氓软件及反流氓软件的技术分析
    标准C++的类型转换符:static_cast、dynamic_cast、reinterpret_cast和const_cast
    C++资料下载
    unix系统操作命令大全
  • 原文地址:https://www.cnblogs.com/Mike-Fighting/p/5125417.html
Copyright © 2011-2022 走看看