用户在微信公众平台(申请扫码支付、公众号支付)或开放平台(申请APP支付)按照相应提示,申请相应微信支付模式。微信支付工作人 员审核资料无误后开通相应的微信支付权限。微信支付申请审核通过后,商户在申请资料填写的邮箱中收取到由微信支付小助手发送的 邮件,此邮件包含开发时需要使用的支付账户信息。

邮件中的账户参数与接口API参数对应关系见下表格

邮件中参数 API参数名 详细说明
APPID appid appid是微信公众账号或开放平台APP的唯一标识,在公众平台申请公众账号或者在开放平台申请APP账号后,微信会自动分配对 应的appid,用于标识该应用。可在微信公众平台-->开发者中心查看,商户的微信支付审核通过邮件中也会包含该字段值。
微信支付商户号 mch_id 商户申请微信支付后,由微信支付分配的商户收款账号。
API密钥 key 交易过程生成签名的密钥,仅保留在商户系统和微信支付后台,不会在网络中传播。商户妥善保管该Key,切勿在网络中传输, 不能在其他客户端中存储,保证key不会被泄漏。商户可根据邮件提示登录微信商户平台进行设置。也可按一下路径设置:微信 商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置
Appsecret secret AppSecret是APPID对应的接口密码,用于获取接口调用凭证access_token时使用。

商户接入微信支付,调用API必须遵循以下规则:

传输方式 为保证交易安全性,采用HTTPS传输
提交方式 采用POST方法提交
数据格式 提交和返回数据都为XML格式,根节点名为xml
字符编码 统一采用UTF-8字符编码
签名算法 MD5,后续会兼容SHA1、SHA256、HMAC等。
签名要求 请求和接收数据均需要校验签名,详细方法请参考安全规范-签名算法
证书要求 调用申请退款、撤销订单接口需要商户证书
判断逻辑 先判断协议字段返回,再判断业务返回,最后判断交易状态

以下是交互时序图,统一下单API、支付结果通知API和查询订单API等都涉及签名过程,调用都必须在商户服务器端完成。如图8.6所示。

APP支付时序图

图8.6 APP支付时序图

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

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

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

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

步骤4:商户APP调起微信支付。api参见本章节【app端开发步骤说明

步骤5:商户后台接收支付通知。api参见【支付结果通知API

步骤6:商户后台查询支付结果。,api参见【查询订单API

具体步骤

1.导入SDK文件

这里写图片描述

2.导入相关的系统库及文件。不导入会报错。

1.SystemConfiguration.framework
    2.libz.tbd
    3.libsqlite3.0.tbd
    4.CoreTelephony.framework

3.配置info.plist

a. schemes ,注意,item0 这里要修改成商户自己的APPID

这里写图片描述

或者这样修改:

这里写图片描述

b.白名单

这里写图片描述

c. 安全配置支持Http

这里写图片描述

当然这部分的配置,也可以通过修改XML来实现。
这里写图片描述

4.修改bitcode。

这里写图片描述

修改:

这里写图片描述

5.在AppDelegate 注册微信

导入#import “WXApiManager.h”

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //向微信注册wxd930ea5d5a258f4f
    [WXApi registerApp:@"wxb4ba3c02aa476ea1" withDescription:@"demo 2.0"];

    return YES;
    }

    - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
    return  [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];
    }

    - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];
    }

6.接下来,就是发起请求支付了,实现上核心代码只有几行。

这部分代码在demo的WXApiRequestHandler–》jumpToBizPay 里。


    //调起微信支付
    PayReq* req             = [[[PayReq alloc] init]autorelease];
    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];

7.不管支付成功还是失败,结果会返回到WXApiManager–》onResp 方法下

 switch (resp.errCode) {
    case WXSuccess:
    strMsg = @"支付结果:成功!";
    NSLog(@"支付成功-PaySuccess,retcode = %d", resp.errCode);
    break;

    default:
    strMsg = [NSString stringWithFormat:@"支付结果:失败!retcode = %d, retstr = %@", resp.errCode,resp.errStr];
    NSLog(@"错误,retcode = %d, retstr = %@", resp.errCode,resp.errStr);
    break;
    }

客户端进行签名

1.导入文件。官方已经不提供这个SDK的下载了,我已经打包到源代码了,2015年3月11号最新修改的版本

这里写图片描述

2.里面有两个文件是非arc的,我们需要设置一下 -fno-objc-arc

这里写图片描述

3.导入系统库及info.list配置,请参数上面服务端签名。

4.AppDelegate配置

1)导入头文件

#import "WXApi.h"
    #import "payRequsestHandler.h"
  • 1
  • 2

2)实现微信代理

@interface AppDelegate ()<WXApiDelegate>

    @end
  • 1
  • 2
  • 3

3)注册微信,及微信支付回调

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    //向微信注册
    [WXApi registerApp:APP_ID withDescription:@"demo 2.0"];

    return YES;
    }

    - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
    {
    return  [WXApi handleOpenURL:url delegate:self];
    }

    - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
    {
    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);
    break;

    default:
    strMsg = [NSString stringWithFormat:@"支付结果:失败!retcode = %d, retstr = %@", resp.errCode,resp.errStr];
    NSLog(@"错误,retcode = %d, retstr = %@", resp.errCode,resp.errStr);
    break;
    }
    }
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:strTitle message:strMsg delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
    [alert show];
    }

5.写方法直接在支付时调用

- (void)payForWechat
    {
    //创建支付签名对象
    payRequsestHandler *req = [[payRequsestHandler alloc] init];
    //初始化支付签名对象
    [req init:APP_ID mch_id:MCH_ID];
    //设置密钥
    [req setKey:PARTNER_ID];

    NSMutableDictionary *dict = [req sendPay_demo];

    if(dict != nil){
    NSMutableString *retcode = [dict objectForKey:@"retcode"];
    if (retcode.intValue == 0){
    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];
    //日志输出
    NSLog(@"appid=%@\npartid=%@\nprepayid=%@\nnoncestr=%@\ntimestamp=%ld\npackage=%@\nsign=%@",req.openID,req.partnerId,req.prepayId,req.nonceStr,(long)req.timeStamp,req.package,req.sign );
    }else{
    [self alert:@"提示信息" msg:[dict objectForKey:@"retmsg"]];
    }
    }else{
    [self alert:@"提示信息" msg:@"服务器返回错误,未获取到json对象"];
    }
    }

    //客户端提示信息
    - (void)alert:(NSString *)title msg:(NSString *)msg
    {
    UIAlertView *alter = [[UIAlertView alloc] initWithTitle:title message:msg delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];

    [alter show];
    }

最后,修改payRequsestHandler.h文件里的APP_ID 和MCH_ID即可使用。