zoukankan      html  css  js  c++  java
  • iOS 微信支付总结

    1.支付流程

    https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=8_3

    商户系统和微信支付系统主要交互说明:

    步骤1:用户在商户APP中选择商品,提交订单,选择微信支付。

    步骤2:商户后台收到用户支付单,调用微信支付统一下单接口。

    步骤3:统一下单接口返回正常的prepay_id,再按签名规范重新生成签名后,将数据传输给APP。参与签名的字段名为appId,partnerId,prepayId,nonceStr,timeStamp,package。注意:package的值格式为Sign=WXPay

    步骤4:商户APP调起微信支付。

    步骤5:商户后台接收支付通知。

    步骤6:商户后台查询支付结果。

    2. 将微信支付的SDK塞进工程

    3.配置info.plist

    a.schemes

    b.白名单

    c.安全配置支持Http

    4.配置路径

    Library search Paths : $(PROJECT_DIR)/XWMerchant/ThirdParts/Wechat/SDKExport

    5. 配置payRequsestHandler.h文件

    #define APPP_ID         @""               //APPID

    #define APP_SECRET      @"" //appsecret

    //商户号,填写商户对应参数

    #define MCH_ID          @""

    //商户API密钥,填写相应参数为了MD5加密

    #define PARTNER_ID      @""

    //支付结果回调页面

    #define NOTIFY_URL      @"http://wxpay.weixin.qq.com/pub_v2/pay/notify.v2.php"

    //获取服务器端支付数据地址(商户自定义)

    #define SP_URL          @"http://wxpay.weixin.qq.com/pub_v2/app/app_pay.php"

    6.支付

    a.在

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 方法中注册一下先:

    if ([WXApi registerApp:APPP_ID withDescription:@"weixin"]){

            DLog(@"注册成功");

        }else{

            DLog(@"注册失败");

        }

    b.在

    - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation代理中

    if ([url.host isEqualToString:@"pay"]) {

            [WXApi handleOpenURL:url delegate:self];

        }支持回调

    c.在需要支付的页面调用如下方法,记得包含头文件

    #pragma mark   ==============微信支付==============
    
    - (void) wechatPay:(NSDictionary *)dic{//目前只需要prepay_id
        NSLog(@"开始微信支付");
    
        //首先判断是否安装wechat
        
        if([WXApi isWXAppInstalled]){
            
            //生成订单
                
            NSLog(@"l-----:%@ ",dic);
        
            NSString *prePayid = dic[@"prepay_id"];
            
    //        //获取到prepayid后进行第二次签名
            
            NSString    *package, *time_stamp, *nonce_str;
            //设置支付参数
            time_t now;
            time(&now);
            time_stamp  = [NSString stringWithFormat:@"%ld", now];
            nonce_str    = [WXUtil md5:time_stamp];
            //重新按提交格式组包,微信客户端暂只支持package=Sign=WXPay格式,须考虑升级后支持携带package具体参数的情况
            //package       = [NSString stringWithFormat:@"Sign=%@",package];
            package         = @"Sign=WXPay";
            //第二次签名参数列表
            NSMutableDictionary *signParams = [NSMutableDictionary dictionary];
            [signParams setObject: APPP_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"];
            //[signParams setObject: @"MD5"       forKey:@"signType"];
            //生成签名
            NSString *sign  = [self createMd5Sign:signParams];//获取微信预付款id
            if ( prePayid != nil && sign != nil) {//调起微信支付
                PayReq* req             = [[PayReq alloc] init];
                req.openID              = APPP_ID;//
                req.partnerId           = MCH_ID;//商户号
                req.prepayId            = prePayid;//预付订单号,后台返回的
                req.nonceStr            = nonce_str;//随机串            req.timeStamp           = time_stamp.intValue;//时间戳            req.package             = @"Sign=WXPay";//此地方一定要写成这种格式,后台生成预付订单时也是如此,不要写成prepay_id = @"wx...."
                req.sign                = sign;            BOOL sendRes = [WXApi sendReq:req];
                if (sendRes) {
                    NSLog(@"唤起成功");
                }else {
                    NSLog(@"唤起失败");
                    
                }
                //日志输出
                DLog(@"appid=%@
    partid=%@
    prepayid=%@
    noncestr=%@
    timestamp=%ld
    package=%@
    sign=%@",req.openID,req.partnerId,req.prepayId,req.nonceStr,(long)req.timeStamp,req.package,req.sign );
            }else{
                DLog(@"预付订单生成失败");
                [XWPrompt showPromptMessage:@"订单失败"];
            }
            
        }else{
            
            [SMAlertView showAlertWithTitle:@"您还没有安装微信" message:@"是否安装?" cancelTitle:@"" cancelTitleColor:colorForDeepGrayNormal otherTitle:@"" otherTitleColor:colorForNavBgColor completion:^(BOOL cancelled) {
                
                if (!cancelled) {
                    
                    DLog(@"%d",cancelled);
                    
                    [[ UIApplication sharedApplication] openURL:[NSURL URLWithString:[WXApi getWXAppInstallUrl]]];
                    
                }
            }];
            
        }
    }
    
    //创建package签名
    -(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_ID];
        //得到MD5 sign签名
        NSString *md5Sign =[WXUtil md5:contentString];
        
        return md5Sign;
    }

    基本上就能支付成功了,如不成功,请仔细检查一下plist文件的配置白名单,安全,sechems,路径,密钥PARTNER_ID,一定要二次签名,要不支付不成功,特别是唤起支付时[WXApi sendReq:req];总是不成功,而且后台生成预付订单时一定要package = @"Sign=WXPay" ,另一个最他妈坑的就是一定不要用shareSDK,它里面的微信分享的包和微信支付的包冲突,会唤起失败,我就是把shareSDK删除了就能唤起支付页面。微信分享用官网自带的吧,不要用第三分的集成了,太他妈的坑了,坑了半天的时间。就此支付成功了。。。。

  • 相关阅读:
    异常解决:swagger2.9.2 报java.lang.NumberFormatException: For input string: ““...
    SpringBoot中使用热部署插件
    SpringBoot中使用自定义拦截器
    SpringBoot开发的接口实现RESTFull的设计风格
    SpringBoot中使用jsp页面的方法
    SpringBoot的自定义配置方法二,通过@Value注解
    SpringBoot的自定义配置方法一,通过自定义配置文件
    Eclipse中使用Mybatis Generator自动生成POJO类、mapper类等
    Eclipse中将Maven工程转成SpringBoot工程
    相对高效的遍历Map的方法,其他方法效率相对较低
  • 原文地址:https://www.cnblogs.com/yyzanll/p/4981465.html
Copyright © 2011-2022 走看看