iOS之“微信支付”开发流程

来源:互联网 发布:淘宝企业店铺怎么纳税 编辑:程序博客网 时间:2024/05/02 01:05

实现微信支付的开发,iOS端里面只需要四个步骤:

  • 向服务端请求预支付,获得prepayid以及noncestr;

  • 把参数拼起来签名;

  • 发起支付请求;

  • 处理支付结果。

iOS的微信SDK的接入:即为“向微信注册你的应用程序id”、“下载微信终端SDK文件”、“搭建开发环境”、“在代码中使用开发工具包”。
详情请参看iOS的接入指南:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=1417694084&token=96a6fb085dbc61bcafd732d1469e5fd0e20c9819&lang=zh_CN

导入微信支付库:
开发者需要在工程中链接上:SystemConfiguration.framework,libz.dylib,libsqlite3.0.dylib,最重要的库是libc++.dylib;

iOS微信支付的具体流程:

  • 向服务端请求预支付,获得prepayid以及noncestr
//提交预支付- (NSString *)sendPrepay:(NSMutableDictionary *)prePayParams {    NSString *prepayid = nil;    //获取提交支付    NSString *send = [self genPackage:prePayParams];    //输出Debug Info    [debugInfo appendFormat:@"API链接:%@\n", payUrl];    [debugInfo appendFormat:@"发送的xml:%@\n", send];    //发送请求post xml数据    NSData *res = [WXUtil httpSend:payUrl method:@"POST" data:send];    //输出Debug Info    [debugInfo appendFormat:@"服务器返回:\n%@\n\n",[[NSString alloc] initWithData:res encoding:NSUTF8StringEncoding]];    XMLHelper *xml  = [XMLHelper alloc];    //开始解析    [xml startParse:res];    NSMutableDictionary *resParams = [xml getDict];    //判断返回    NSString *return_code   = [resParams objectForKey:@"return_code"];    NSString *result_code   = [resParams objectForKey:@"result_code"];    if ([return_code isEqualToString:@"SUCCESS"]) {        //生成返回数据的签名        NSString *sign      = [self createMd5Sign:resParams ];        NSString *send_sign =[resParams objectForKey:@"sign"] ;        //验证签名正确性        if( [sign isEqualToString:send_sign]) {            if( [result_code isEqualToString:@"SUCCESS"]) {                //验证业务处理状态                prepayid    = [resParams objectForKey:@"prepay_id"];                return_code = 0;                [debugInfo appendFormat:@"获取预支付交易标示成功!\n"];            }        }else{            last_errcode = 1;            [debugInfo appendFormat:@"gen_sign=%@\n   _sign=%@\n",sign,send_sign];            [debugInfo appendFormat:@"服务器返回签名验证错误!!!\n"];        }    }else{        last_errcode = 2;        [debugInfo appendFormat:@"接口返回错误!!!\n"];    }    return prepayid;}- (NSMutableDictionary *)sendPay_WithPrice:(NSString *)order_price orderNo:(NSString *)orderNo {    //订单标题,展示给用户    NSString *order_name = @"展示给用户的订单标题";    //预付单参数订单设置    srand( (unsigned)time(0) );    NSString *noncestr  = [NSString stringWithFormat:@"%d", rand()];    NSString *orderno   = orderNo;    NSMutableDictionary *packageParams = [NSMutableDictionary dictionary];    [packageParams setObject: appid          forKey:@"appid"];           //开放平台appid    [packageParams setObject: mchid          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: order_name     forKey:@"body"];            //订单描述,展示给用户    [packageParams setObject: NOTIFY_URL     forKey:@"notify_url"];      //支付结果异步通知    [packageParams setObject: orderno        forKey:@"out_trade_no"];    //商户订单号    [packageParams setObject: @"196.168.1.1" forKey:@"spbill_create_ip"];//发器支付的机器ip    [packageParams setObject: order_price    forKey:@"total_fee"];       //订单金额,单位为分    //获取prepayId(预支付交易会话标识)    NSString *prePayid;    prePayid = [self sendPrepay:packageParams];    if ( prePayid != nil) {        //获取到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 = @"Sign=WXPay";        //第二次签名参数列表        NSMutableDictionary *signParams = [NSMutableDictionary dictionary];        [signParams setObject: appid        forKey:@"appid"];        [signParams setObject: nonce_str    forKey:@"noncestr"];        [signParams setObject: package      forKey:@"package"];        [signParams setObject: mchid        forKey:@"partnerid"];        [signParams setObject: time_stamp   forKey:@"timestamp"];        [signParams setObject: prePayid     forKey:@"prepayid"];        //生成签名        NSString *sign = [self createMd5Sign:signParams];        //添加签名        [signParams setObject: sign forKey:@"sign"];        [debugInfo appendFormat:@"第二步签名成功,sign=%@\n",sign];        //返回参数列表        return signParams;    }else{        [debugInfo appendFormat:@"获取prepayid失败!\n"];    }    return nil;}
  • 把参数拼起来签名
//创建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=%@", spkey];    //得到MD5 sign签名    NSString *md5Sign =[WXUtil md5:contentString];    //输出Debug Info    [debugInfo appendFormat:@"MD5签名字符串:\n%@\n\n",contentString];    return md5Sign;}//获取package带参数的签名包- (NSString *)genPackage:(NSMutableDictionary*)packageParams {    NSString *sign;    NSMutableString *reqPars=[NSMutableString string];    //生成签名    sign = [self createMd5Sign:packageParams];    //生成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];}
  • 发起支付请求
- (void)viewWillAppear:(BOOL)animated {    [super viewWillAppear:animated];    //支付结果通知注册    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getOrderPayResult:) name:@"ORDER_PAY_NOTIFICATION" object:nil];}//调用微信支付- (void)viewDidLoad {    [super viewDidLoad];    [self WXPay];}#pragma mark -- 发起”微信支付“请求- (void)WXPay {    if (![WXApi isWXAppInstalled]) {        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"您还没有安装微信" message:nil preferredStyle:UIAlertControllerStyleAlert];        UIAlertAction *sureAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {            //跳转到微信的下载安装地址        }];        [alert addAction:sureAction];        [self.navigationController presentViewController:alert animated:YES completion:nil];        return ;    }    YDWWeChatPayResquest *req = [YDWWeChatPayResquest new];    //初始化支付签名对象    [req init:APP_ID mch_id:MCH_ID];    //设置密钥    [req setKey:PARTNER_ID];    //获取到实际调起微信支付的参数后,在app端调起支付    NSInteger payTheAmount;//支付金额    NSString *orderMeony = [NSString stringWithFormat:@"%ld",payTheAmount];    NSDictionary *orderDic;//支付订单    NSString *orderNo = [orderDic objectForKey:@"orderNumber"];    NSMutableDictionary *dict = [req sendPay_WithPrice:orderMeony orderNo: orderNo];    if(dict == nil){        //错误提示        NSString *debug = [req getDebugifo];        UIAlertController *alert = [UIAlertController alertControllerWithTitle:debug message:nil preferredStyle:UIAlertControllerStyleAlert];        UIAlertAction *sureAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];        [alert addAction:sureAction];        [self.navigationController presentViewController:alert animated:YES completion:nil];    }else{        NSMutableString *stamp  = [dict objectForKey:@"timestamp"];        //调起微信支付        PayReq* req             = [[PayReq alloc] init];        req.openID              = [dict objectForKey:@"appid"];        req.partnerId           = [dict objectForKey:@"partnerid"];        req.prepayId            = [dict objectForKey:@"prepayid"];        req.nonceStr            = [dict objectForKey:@"noncestr"];        req.timeStamp           = stamp.intValue;        req.package             = [dict objectForKey:@"package"];        req.sign                = [dict objectForKey:@"sign"];        [WXApi sendReq:req];    }}- (void)weixinPay {    YDWWeixinPayParams *signParams = [[YDWWeixinPayParams alloc] initWithPrepayid:self.prepay_id noncestr:self.nonce_str];    //调起微信支付    PayReq *req = [[PayReq alloc] init];    req.openID = signParams.appid;    req.partnerId = signParams.partnerid;    req.prepayId = signParams.prepayid;    req.nonceStr = signParams.noncestr;    req.timeStamp = signParams.timestamp.intValue;    req.package = signParams.package;    req.sign = [signParams sign];    [WXApi sendReq:req];}#pragma mark - 支付结果通知信息- (void)getOrderPayResult:(NSNotification *)notification{    if ([notification.object isEqualToString:@"success"]) {        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"恭喜" message:@"您已成功支付啦!" preferredStyle:UIAlertControllerStyleAlert];        UIAlertAction *sureAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];        [alert addAction:sureAction];        [self.navigationController presentViewController:alert animated:YES completion:nil];    }    else    {        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"支付失败,可在待付款订单中查看" preferredStyle:UIAlertControllerStyleAlert];        UIAlertAction *sureAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];        [alert addAction:sureAction];        [self.navigationController presentViewController:alert animated:YES completion:nil];    }}//移除通知- (void)viewWillDisappear:(BOOL)animated{    [[NSNotificationCenter defaultCenter]removeObserver:self];}
  • 处理支付结果,在AppDelegate中做的工作:

1、导入#import “WXApi.h”和#import “WXApiObject.h”,并遵守WXApiDelegate协议,要使你的程序启动后微信终端能响应你的程序,必须在代码中向微信终端注册你的id:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    [WXApi registerApp:@"WXAppId" withDescription:@"YDWWXPayDes"];    return YES;}

2、重写AppDelegate的handleOpenURL和openURL方法:

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{     if ([url.absoluteString hasPrefix:Weixin_Appid]) {        return [WXApi handleOpenURL:url delegate:self];    }     return YES;}- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {    return [WXApi handleOpenURL:url delegate:self];}

3、处理结果:

- (void)onResp:(BaseResp *)resp {    NSString *strMsg = [NSString stringWithFormat:@"errcode:%d", resp.errCode];    NSString *strTitle;    if([resp isKindOfClass:[SendMessageToWXResp class]]) {        strTitle = [NSString stringWithFormat:@"发送媒体消息结果"];    }    if([resp isKindOfClass:[PayResp class]])    {        //支付返回结果,实际支付结果需要去微信服务器端查询        strTitle = [NSString stringWithFormat:@"支付结果"];        switch (resp.errCode) {            case WXSuccess:{                strMsg = @"支付结果:成功!";                NSLog(@"支付成功-PaySuccess,retcode = %d", resp.errCode);                NSNotification *notification = [NSNotification notificationWithName:@"ORDER_PAY_NOTIFICATION" object:@"success"];                [[NSNotificationCenter defaultCenter] postNotification:notification];                break;            }            default:{                strMsg = [NSString stringWithFormat:@"支付结果:失败!retcode = %d, retstr = %@", resp.errCode,resp.errStr];                NSLog(@"错误,retcode = %d, retstr = %@", resp.errCode,resp.errStr);                NSNotification *notification = [NSNotification notificationWithName:@"ORDER_PAY_NOTIFICATION" object:@"fail"];                [[NSNotificationCenter defaultCenter] postNotification:notification];                break;            }        }    }//        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:strTitle message:strMsg delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];//        [alert show];}

常见的问题:
如果跳转到微信里之只弹出了一个确定按钮,那么这时候需要检查几个方面:
1、appid,mch_id,partner_id是否设置正确。mch_id对应的key其实是partnerid,partner_id对应的key其实是key;
2、timestamp 应为10位;
3、签名需要排序,并用md5加密。

最后附上重要的类的全部代码:
AppDelegate:

//  AppDelegate.h//  微信支付////  Created by YDW on 16/3/28.//  Copyright © 2016年 IZHUO.NET. All rights reserved.//#import <UIKit/UIKit.h>#import "WXApi.h"#import "WXApiObject.h"@interface AppDelegate : UIResponder <UIApplicationDelegate,WXApiDelegate>@property (strong, nonatomic) UIWindow *window;@end//  AppDelegate.m//  微信支付////  Created by YDW on 16/3/28.//  Copyright © 2016年 IZHUO.NET. All rights reserved.//#import "AppDelegate.h"@interface AppDelegate ()@end@implementation AppDelegate- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    [WXApi registerApp:@"WXAppId" withDescription:@"YDWWXPayDes"];    return YES;}- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {    return [WXApi handleOpenURL:url delegate:self];}- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {    return  [WXApi handleOpenURL:url delegate:self];}- (void)onResp:(BaseResp *)resp {    NSString *strMsg = [NSString stringWithFormat:@"errcode:%d", resp.errCode];    NSString *strTitle;    if([resp isKindOfClass:[SendMessageToWXResp class]]) {        strTitle = [NSString stringWithFormat:@"发送媒体消息结果"];    }    if([resp isKindOfClass:[PayResp class]])    {        //支付返回结果,实际支付结果需要去微信服务器端查询        strTitle = [NSString stringWithFormat:@"支付结果"];        switch (resp.errCode) {            case WXSuccess:{                strMsg = @"支付结果:成功!";                NSLog(@"支付成功-PaySuccess,retcode = %d", resp.errCode);                NSNotification *notification = [NSNotification notificationWithName:@"ORDER_PAY_NOTIFICATION" object:@"success"];                [[NSNotificationCenter defaultCenter] postNotification:notification];                break;            }            default:{                strMsg = [NSString stringWithFormat:@"支付结果:失败!retcode = %d, retstr = %@", resp.errCode,resp.errStr];                NSLog(@"错误,retcode = %d, retstr = %@", resp.errCode,resp.errStr);                NSNotification *notification = [NSNotification notificationWithName:@"ORDER_PAY_NOTIFICATION" object:@"fail"];                [[NSNotificationCenter defaultCenter] postNotification:notification];                break;            }        }    }//        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:strTitle message:strMsg delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];//        [alert show];}

YDWWeChatPayResquest:

//  YDWWeChatPayResquest.h//  微信支付////  Created by YDW on 16/3/28.//  Copyright © 2016年 IZHUO.NET. All rights reserved.//#import <Foundation/Foundation.h>#import "WXUtil.h"#import "ApiXml.h"/* * 账号的账户资料:更改商户后的相关参数后可以使用 */#define APP_ID        @"你的APP的ID"       //APPID#define APP_SECRET    @"你的APP的secret"   //appsecret#define MCH_ID        @"商户号"            //商户号,填写商户对应参数#define PARTNER_ID    @"商户API密钥"       //商户API密钥,填写相应参数#define NOTIFY_URL    @"回调页面地址"       //支付结果回调页面#define SP_URL        @"服务器端支付数据地址"//获取服务器端支付数据地址(商户自定义)@interface YDWWeChatPayResquest : NSObject {    //预支付的url地址    NSString *payUrl;    //lash_errcode;    long     last_errcode;    //debug信息    NSMutableString *debugInfo;    NSString        *appid,*mchid,*spkey;}- (BOOL)init:(NSString *)app_id mch_id:(NSString *)mch_id;- (NSString *)getDebugifo;- (long)getLasterrCode;//设置商户密钥- (void)setKey:(NSString *)key;//创建package签名- (NSString*)createMd5Sign:(NSMutableDictionary*)dict;//获取package带参数的签名包- (NSString *)genPackage:(NSMutableDictionary*)packageParams;//提交预支付- (NSString *)sendPrepay:(NSMutableDictionary *)prePayParams;- (NSMutableDictionary *)sendPay_WithPrice:(NSString *)order_price orderNo:(NSString *)orderNo;//签名实例测试//- (NSMutableDictionary *)sendPay_demo;@end//  YDWWeChatPayResquest.m//  微信支付////  Created by YDW on 16/3/28.//  Copyright © 2016年 IZHUO.NET. All rights reserved.//#import <Foundation/Foundation.h>#import "YDWWeChatPayResquest.h"@implementation YDWWeChatPayResquest- (BOOL)init:(NSString *)app_id mch_id:(NSString *)mch_id {    payUrl     = @"https://api.mch.weixin.qq.com/pay/unifiedorder";    if (debugInfo == nil){        debugInfo = [NSMutableString string];    }    [debugInfo setString:@""];    appid = app_id;    mchid = mch_id;    return YES;}//设置商户密钥- (void)setKey:(NSString *)key {    spkey = [NSString stringWithString:key];}//获取debug信息- (NSString*)getDebugifo {    NSString *res = [NSString stringWithString:debugInfo];    [debugInfo setString:@""];    return res;}//获取最后服务返回错误代码- (long)getLasterrCode {    return last_errcode;}//创建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=%@", spkey];    //得到MD5 sign签名    NSString *md5Sign =[WXUtil md5:contentString];    //输出Debug Info    [debugInfo appendFormat:@"MD5签名字符串:\n%@\n\n",contentString];    return md5Sign;}//获取package带参数的签名包- (NSString *)genPackage:(NSMutableDictionary*)packageParams {    NSString *sign;    NSMutableString *reqPars=[NSMutableString string];    //生成签名    sign = [self createMd5Sign:packageParams];    //生成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];}//提交预支付- (NSString *)sendPrepay:(NSMutableDictionary *)prePayParams {    NSString *prepayid = nil;    //获取提交支付    NSString *send = [self genPackage:prePayParams];    //输出Debug Info    [debugInfo appendFormat:@"API链接:%@\n", payUrl];    [debugInfo appendFormat:@"发送的xml:%@\n", send];    //发送请求post xml数据    NSData *res = [WXUtil httpSend:payUrl method:@"POST" data:send];    //输出Debug Info    [debugInfo appendFormat:@"服务器返回:\n%@\n\n",[[NSString alloc] initWithData:res encoding:NSUTF8StringEncoding]];    XMLHelper *xml  = [XMLHelper alloc];    //开始解析    [xml startParse:res];    NSMutableDictionary *resParams = [xml getDict];    //判断返回    NSString *return_code   = [resParams objectForKey:@"return_code"];    NSString *result_code   = [resParams objectForKey:@"result_code"];    if ([return_code isEqualToString:@"SUCCESS"]) {        //生成返回数据的签名        NSString *sign      = [self createMd5Sign:resParams ];        NSString *send_sign =[resParams objectForKey:@"sign"] ;        //验证签名正确性        if( [sign isEqualToString:send_sign]) {            if( [result_code isEqualToString:@"SUCCESS"]) {                //验证业务处理状态                prepayid    = [resParams objectForKey:@"prepay_id"];                return_code = 0;                [debugInfo appendFormat:@"获取预支付交易标示成功!\n"];            }        }else{            last_errcode = 1;            [debugInfo appendFormat:@"gen_sign=%@\n   _sign=%@\n",sign,send_sign];            [debugInfo appendFormat:@"服务器返回签名验证错误!!!\n"];        }    }else{        last_errcode = 2;        [debugInfo appendFormat:@"接口返回错误!!!\n"];    }    return prepayid;}- (NSMutableDictionary *)sendPay_WithPrice:(NSString *)order_price orderNo:(NSString *)orderNo {    //订单标题,展示给用户    NSString *order_name = @"展示给用户的订单标题";    //预付单参数订单设置    srand( (unsigned)time(0) );    NSString *noncestr  = [NSString stringWithFormat:@"%d", rand()];    NSString *orderno   = orderNo;    NSMutableDictionary *packageParams = [NSMutableDictionary dictionary];    [packageParams setObject: appid          forKey:@"appid"];           //开放平台appid    [packageParams setObject: mchid          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: order_name     forKey:@"body"];            //订单描述,展示给用户    [packageParams setObject: NOTIFY_URL     forKey:@"notify_url"];      //支付结果异步通知    [packageParams setObject: orderno        forKey:@"out_trade_no"];    //商户订单号    [packageParams setObject: @"196.168.1.1" forKey:@"spbill_create_ip"];//发器支付的机器ip    [packageParams setObject: order_price    forKey:@"total_fee"];       //订单金额,单位为分    //获取prepayId(预支付交易会话标识)    NSString *prePayid;    prePayid            = [self sendPrepay:packageParams];    if ( prePayid != nil) {        //获取到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         = @"Sign=WXPay";        //第二次签名参数列表        NSMutableDictionary *signParams = [NSMutableDictionary dictionary];        [signParams setObject: appid        forKey:@"appid"];        [signParams setObject: nonce_str    forKey:@"noncestr"];        [signParams setObject: package      forKey:@"package"];        [signParams setObject: mchid        forKey:@"partnerid"];        [signParams setObject: time_stamp   forKey:@"timestamp"];        [signParams setObject: prePayid     forKey:@"prepayid"];        //生成签名        NSString *sign = [self createMd5Sign:signParams];        //添加签名        [signParams setObject: sign forKey:@"sign"];        [debugInfo appendFormat:@"第二步签名成功,sign=%@\n",sign];        //返回参数列表        return signParams;    }else{        [debugInfo appendFormat:@"获取prepayid失败!\n"];    }    return nil;}@end

调用微信支付的页面:

@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    [self WXPay];}- (void)viewWillAppear:(BOOL)animated {    [super viewWillAppear:animated];    //支付结果通知注册    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getOrderPayResult:) name:@"ORDER_PAY_NOTIFICATION" object:nil];}#pragma mark -- 发起”微信支付“请求- (void)WXPay {    if (![WXApi isWXAppInstalled]) {        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"您还没有安装微信" message:nil preferredStyle:UIAlertControllerStyleAlert];        UIAlertAction *sureAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {            //跳转到微信的下载安装地址        }];        [alert addAction:sureAction];        [self.navigationController presentViewController:alert animated:YES completion:nil];        return ;    }    YDWWeChatPayResquest *req = [YDWWeChatPayResquest new];    //初始化支付签名对象    [req init:APP_ID mch_id:MCH_ID];    //设置密钥    [req setKey:PARTNER_ID];    //获取到实际调起微信支付的参数后,在app端调起支付    NSInteger payTheAmount;//支付金额    NSString *orderMeony = [NSString stringWithFormat:@"%ld",payTheAmount];    NSDictionary *orderDic;//支付订单    NSString *orderNo = [orderDic objectForKey:@"orderNumber"];    NSMutableDictionary *dict = [req sendPay_WithPrice:orderMeony orderNo: orderNo];    if(dict == nil){        //错误提示        NSString *debug = [req getDebugifo];        UIAlertController *alert = [UIAlertController alertControllerWithTitle:debug message:nil preferredStyle:UIAlertControllerStyleAlert];        UIAlertAction *sureAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];        [alert addAction:sureAction];        [self.navigationController presentViewController:alert animated:YES completion:nil];    }else{        NSMutableString *stamp  = [dict objectForKey:@"timestamp"];        //调起微信支付        PayReq* req             = [[PayReq alloc] init];        req.openID              = [dict objectForKey:@"appid"];        req.partnerId           = [dict objectForKey:@"partnerid"];        req.prepayId            = [dict objectForKey:@"prepayid"];        req.nonceStr            = [dict objectForKey:@"noncestr"];        req.timeStamp           = stamp.intValue;        req.package             = [dict objectForKey:@"package"];        req.sign                = [dict objectForKey:@"sign"];        [WXApi sendReq:req];    }}#pragma mark - 支付结果通知信息- (void)getOrderPayResult:(NSNotification *)notification{    if ([notification.object isEqualToString:@"success"]) {        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"恭喜" message:@"您已成功支付啦!" preferredStyle:UIAlertControllerStyleAlert];        UIAlertAction *sureAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];        [alert addAction:sureAction];        [self.navigationController presentViewController:alert animated:YES completion:nil];    }    else    {        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"支付失败,可在待付款订单中查看" preferredStyle:UIAlertControllerStyleAlert];        UIAlertAction *sureAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];        [alert addAction:sureAction];        [self.navigationController presentViewController:alert animated:YES completion:nil];    }}//移除通知- (void)viewWillDisappear:(BOOL)animated{    [[NSNotificationCenter defaultCenter]removeObserver:self];}@end

参考资料:
http://www.cocoachina.com/bbs/read.php?tid=303132

1 0