您的位置:首页 > 移动开发 > 微信开发

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

2016-03-27 16:31 561 查看
实现微信支付的开发,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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息