在吊起微信之前,必须要知道微信支付是一个怎么样的过程。
【了解一下-官方流程】
商户系统和微信支付系统主要交互说明:
步骤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、用户使用APP客户端,选择商品下单。
2、商户客户端(就是你做的APP)将用户的商品数据传给商户服务器,请求生成支付订单。
3、商户后台调用统一下单API向微信的服务器发送请求,微信服务器生成预付单,并生成一个prepay_id返回给商户后台。
4、商户后台将这个prepay_id返回给商户客户端。
5、用户点击确认支付,这时候商户客户端调用SDK打开微信客户端,进行微信支付。
6、微信客户端向微信服务器发起支付请求并返回支付结果(他们之间交互用的就是prepay_id这个参数,微信的服务器要验证微信客户端传过去的参数是否跟第三步中生成的那个id一致)。
7、用户输入支付密码后,微信客户端提交支付授权,跟微信服务器交互,完成支付。
8、微信服务器给微信客户端发送支付结果提示,并异步给商户服务器发送支付结果通知。
9、商户客户端通过支付结果回调接口查询支付结果,并向后台检查支付结果是否正确,后台返回支付结果。
10、商户客户端显示支付结果,完成订单,发货。
客户端主要工作
1.调起微信客户端发起支付
2.显示支付结果
吊起准备
调用微信支付前,需要下单、签名等操作,以便获取微信支付所必要的参数。为了提高安全性,下单、签名操作一般是在后台完成。
需要的参数包括:appid、partid(商户号)、prepayid(预支付订单ID)、noncestr(参与签名的随机字符串)、timestamp(参与签名的时间戳)、sign(签名字符串)这六个。
[代码示例①:]
如果所有信息的生成都在前端完成,包括对订单进行sign签名以及MD5签名加密(此方法相对来说有些复杂,没有官方给的方法简单)您可以看参考文章iOS应用之微信支付集成。
官方给的是v3&v4支付流程,签名和加密都是在[服务器端],我们也是这样做的,服务器做的2次签名如下:
1、在项目工程Appdelegate.m文件里面添加注册微信支付信息,注:如果项目中第三方分享用的是友盟,在注册的时候要把友盟注册放在微信注册的前面执行。如下:
#import "AppDelegate.h"
#import "WXApi.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//注册APP,
[WXApi registerApp:@"wxb4ba3c02aa476ea1"];
return YES;
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options
{
// 跳转到URL scheme中配置的地址
//NSLog(@"跳转到URL scheme中配置的地址-->%@",url);
return [WXApi handleOpenURL:url delegate:(id)self];
}
//支付成功时调用,回到第三方应用中
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
// NSLog(@"****************url.host -- %@",url.host);
if ([url.scheme isEqualToString:@"wx23a1f7f291ef4b3d"])
{
return [WXApi handleOpenURL:url delegate:(id)self];
}
return YES;
}
2、给服务器发送订单信息,获取预付订单参数,吊起微信。
WechatPayViewController.m
#import "WechatPayViewController.h"
#import "HYBNetworking.h"
#import "WXApi.h"
#import "NSString+MD5.h"
@interface WechatPayViewController ()
//商户关键信息 ,微信分配给商户的appID,商户号,商户的密钥
@property (nonatomic,strong) NSString *appId,*mchId,*spKey;
@end
@implementation WechatPayViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor greenColor];
UIButton *payButton = [UIButton buttonWithType:UIButtonTypeCustom];
payButton.center = self.view.center;
payButton.bounds = CGRectMake(0, 0, 200, 200);
[payButton setImage:[UIImage imageNamed:@"wechatPay_icon@2x"] forState:UIControlStateNormal];
[payButton addTarget:self action:@selector(payClick) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:payButton];
// 判断 用户是否安装微信
//如果判断结果一直为NO,可能appid无效,这里的是无效的
if([WXApi isWXAppInstalled])
{
// 监听一个通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getOrderPayResult:) name:@"ORDER_PAY_NOTIFICATION" object:nil];
}
}
-(void)payClick {
[self easyPay];
}
/**
http://wxpay.weixin.qq.com/pub_v2/app/app_pay.php为测试数据,一般可以从这儿拿
到的数据都可以让服务器端去完成,客户端只需获取到然后配置到PayReq,即可吊起微信;
*/
-(void)easyPay {
[HYBNetworking getWithUrl:@"http://wxpay.weixin.qq.com/pub_v2/app/app_pay.php" params:nil success:^(id response) {
NSLog(@"%@",response);
//配置调起微信支付所需要的参数
PayReq *req = [[PayReq alloc] init];
req.partnerId = [response objectForKey:@"partnerid"];
req.prepayId = [response objectForKey:@"prepayid"];
req.package = [response objectForKey:@"package"];
req.nonceStr = [response objectForKey:@"noncestr"];
req.timeStamp = [[response objectForKey:@"timestamp"]intValue];
req.sign = [response objectForKey:@"sign"];
//调起微信支付
if ([WXApi sendReq:req]) {
NSLog(@"吊起成功");
}
} fail:^(NSError *error) {
NSLog(@"%@",error);
}];
}
#pragma mark - 收到支付成功的消息后作相应的处理
- (void)getOrderPayResult:(NSNotification *)notification
{
if ([notification.object isEqualToString:@"success"]) {
NSLog(@"支付成功");
} else {
NSLog(@"支付失败");
}
}