iOS开发技术之微信支付

一、微信支付简易流程:

用户 —》微信客户端 —》商户APP —》商户后台应用 —》微信支付系统

 

二、微信支付顺序流程:

1、用户使用APP客户端,选择商品下单。

2、商户客户端(就是你做的APP)将用户的商品数据传给商户服务器,请求生成支付订单。

3、商户后台调用统一下单API向微信的服务器发送请求,微信服务器生成预付单,并生成一个prepay_id返回给商户后台。

4、商户后台将这个prepay_id返回给商户客户端。

5、用户点击确认支付,这时候商户客户端调用SDK打开微信客户端,进行微信支付。

6、微信客户端向微信服务器发起支付请求并返回支付结果(他们之间交互用的就是prepay_id这个参数,微信的服务器要验证微信客户端传过去的参数是否跟第三步中生成的那个id一致)。

7、用户输入支付密码后,微信客户端提交支付授权,跟微信服务器交互,完成支付

8、微信服务器给微信客户端发送支付结果提示,并异步给商户服务器发送支付结果通知。

9、商户客户端通过支付结果回调接口查询支付结果,并向后台检查支付结果是否正确,后台返回支付结果。

10、商户客户端显示支付结果,完成订单,发货。

 

三、集成微信SDK步骤:

1、下载SDK

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

 

2、导入微信支付SDK库

  • SystemConfiguration.framework
  • libz.tbd
  • libsqlite3.0.tbd
  • CoreTelephony.framework
  • QuartzCore.framework

 

3、设置URL Scheme

Target —> info —> URL Types —> URL Scheme(wxd930ea5d5a258f4f)

 

4、在Appdelegate中注册APPID

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. /** * 向微信终端注册ID,这里的APPID一般建议写成宏,容易维护。@“测试demo”不需用管。这里的id是假的,需要改这里还有target里面的URL Type */ [WXApi registerApp:@"wxd930ea5d5a258f4f" withDescription:@"测试demo"]; return YES; }

 

 

5、处理微信通过URL启动时传递的数据

//9.0前的方法,为了适配低版本 保留 

- (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]; 

}

 

//9.0后的方法 

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options{ 

//这里判断是否发起的请求为微信支付,如果是的话,用WXApi的方法调起微信客户端的支付页面(://pay 之前的那串字符串就是你的APPID,) 

return [WXApi handleOpenURL:url delegate:self]; 

} 

 

//微信SDK自带的方法,处理从微信客户端完成操作后返回程序之后的回调方法,显示支付结果的 

-(void) onResp:(BaseResp*)resp { 

//启动微信支付的response 

NSString *payResoult = [NSString stringWithFormat:@errcode:%d, resp.errCode]; if([resp isKindOfClass:[PayResp class]]){ 

//支付返回结果,实际支付结果需要去微信服务器端查询 

switch (resp.errCode) { 

case 0: payResoult = @支付结果:成功!; break; 

case -1: payResoult = @支付结果:失败!; break; 

case -2: payResoult = @用户已经退出支付!; break; 

default: payResoult = [NSString stringWithFormat:@支付结果:失败!retcode = %d, retstr = %@, resp.errCode,resp.errStr]; break; 

    }

  } 

}

 

6、 必须填写的参数

appid、partid(商户号)、prepayid(预支付订单ID)、noncestr(参与签名的随机字符串)、timestamp(参与签名的时间戳)、sign(签名字符串)

 

7、 核心代码

#pragma mark 微信支付方法 - (void)WXPay{ 

//需要创建这个支付对象 PayReq *req = [[PayReq alloc] init]; 

//由用户微信号和AppID组成的唯一标识,用于校验微信用户 req.openID = @""; 

// 商家id,在注册的时候给的 req.partnerId = @""; 

// 预支付订单这个是后台跟微信服务器交互后,微信服务器传给你们服务器的,你们服务器再传给你 req.prepayId = @""; 

// 根据财付通文档填写的数据和签名 //这个比较特殊,是固定的,只能是即req.package = Sign=WXPay req.package = @""; 

// 随机编码,为了防止重复的,在后台生成 req.nonceStr = @""; 

// 这个是时间戳,也是在后台生成的,为了验证支付的 NSString * stamp = @""; req.timeStamp = stamp.intValue; 

// 这个签名也是后台做的 req.sign = @""; 

//发送请求到微信,等待微信返回onResp [WXApi sendReq:req];

}

 

8、后台返回的JSON数据

{ "appid": "wxb4ba3c02aa476ea1", "noncestr": "d1e6ecd5993ad2d06a9f50da607c971c", "package": "Sign=WXPay", "partnerid": "10000100", "prepayid": "wx20160218122935e3753eda1f0066087993", "timestamp": "1455769775", "sign": "F6DEE4ADD82217782919A1696500AF06" 

}

 

注意事项:

1.如果支付完成后,一直留在微信,那就检查下URLType中的Scheme设置问题。

2.能够打开微信客户端,但是打开后只有中间一个白色的 “确定按钮”,点击后会回到客户端上,如果是这样,那应该是prepayid 参数的问题,过期了,或者不是真实的id。代码没有问题的。特别注意的是,微信要两次签名。

3.如果APP里面使用了友盟或者ShareSDK做分享,那就不用再导入SDK了,否则会出现一些诡异的问题,例如无法调起手机微信客户端、无法调起微信客户端web页面,调起了但是一闪而过。。。这都基本上都是因为分享的SDK里面已经包括了微信的SDK。所以如果出现诡异的错误了看看是不是两个冲突了!

4.微信支付的单位是分。

 

原文地址:https://www.cnblogs.com/yuhao309/p/7280665.html