微信APP支付(IOS手机端+java后台)版

网友投稿 240 2023-01-07


微信APP支付(IOS手机端+java后台)版

0.介绍预览

针对需要在IOS手机上接入原生微信支付场景,调用微信进行支付。如图:

1.资料准备

1.1 账号注册

打开https://open.weixin.qq.com,注册微信开放平台开发者账号

1.2 开发者认证

登录,进入账号中心,进行开发者资质认证。

1.3 注册应用

认证完成后,进入管理中心,新建移动应用。填写应用资料,其中android版应用签名可通过扫码安装温馨提供的应用获得,详细参考微信文档。创建完成后点击查看,申请开通微信支付。一切准备就绪!

2.java后台开发

添加依赖

org.xmlpull

xmlpull

1.1.3.1

net.sf.json-lib

json-lib

2.3

jdk15

com.thoughtworks.xstream

xstream

1.4.5

com.ning

async-http-client

1.8.13

生成统一订单

@RequestMapping(value="/pay/wxpay/params",produces="application/json;charset=utf-8")

@ResponseBody

public String signprams(HttpServletRequest request){

String res = "{code:404}";

try{

// 充值金额

String account = request.getParameter("account");

// 用户id

String sid = request.getParameter("sid");

String subject = "订单标题";

String body = "订单描述";

int acc = (int) (Double.valueOf(account) * 100);

String appid = "您的APPID";

String out_trade_no = "生成您的订单号";

// 生成订单数据

SortedMap payMap = genOrderData(request, subject, body, acc, appid, out_trade_no);

savePayLog(out_trade_no,account,sid,body,payMap.get("paySign"),nid,2);

// 4.返回数据

res = buildPayRes(payMap,out_trade_no);

}catch (Exception e){

e.printStackTrace();

res = "{code:500}";

}

return res;

}

private SortedMap genOrderData(HttpServletRequest request, String subject, String body,

int acc, String appid, String out_trade_no)

throws IOException, ExecutionException, InterruptedException, XmlPullParserException {

SortedMap paraMap = new TreeMap();

paraMap.put("appid", appid);

paraMap.put("attach", subject);

paraMap.put("body", body);

paraMap.put("mch_id", "您的商户id,到商户平台查看");

paraMap.put("nonce_str", create_nonce_str());

paraMap.put("notify_url", "http://pay.xxxxx.com/pay/wxpay/notify.htm ");// 此路径是微信服务器调用支付结果通知路径

paraMap.put("out_trade_no", out_trade_no);

paraMap.put("spbill_create_ip", request.getRemoteAddr());

paraMap.put("total_fee", acc+"");

paraMap.put("trade_type", "APP");

String sign = createSign(paraMap);

paraMap.put("sign", sign);

// 统一下单 https://api.mch.weixin.qq.com/pay/unifiedorder

String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";

String xml = getRequestXml(paraMap);

String xmlStr = HttpKit.post(url, xml);

// 预付商品id

String prepay_id = "";

if (xmlStr.indexOf("SUCCESS") != -1) {

Map map = WXRequestUtil.doXMLParse(xmlStr);

prepay_id = (String) map.get("prepay_id");

}

SortedMap payMap = new TreeMap();

payMap.put("appid", appid);

payMap.put("partnerid", "您的商户id,到商户平台查看");

payMap.put("prepayid", prepay_id);

payMap.put("package", "Sign=WXPay");

payMap.put("noncestr", create_nonce_str());

payMap.put("timestamp", WXRequestUtil.create_timestamp());

String paySign = createSign(payMap);

payMap.put("paySign", paySign);

return payMap;

}

//请求xml组装

public static String getRequestXml(SortedMap parameters){

String sign = "";

StringBuffer sb = new StringBuffer();

sb.append("");

Set es = parameters.entrySet();

Iterator it = es.iterator();

while(it.hasNext()) {

Map.Entry entry = (Map.Entry)it.next();

String key = (String)entry.getKey();

String value = (String)entry.getValue();

// if ("attach".equalsIgnoreCase(key)||"body".equalsIgnoreCase(key)||"sign".equalsIgnoreCase(key)) {

// sb.append("<"+key+">"+value+""+key+">");

// }

if ("sign".equalsIgnoreCase(key)){

sign = "<"+key+">"+value+""+key+">";

}else {

sb.append("<"+key+">"+value+""+key+">");

}

}

sb.append(sign);

sb.append("");

return sb.toString();

}

//生成签名

public String createSign(SortedMap parameters){

StringBuffer sb = new StringBuffer();

Set es = parameters.entrySet();

Iterator it = es.iterator();

while(it.hasNext()) {

Map.Entry entry = (Map.Entry)it.next();

String k = (String)entry.getKey();

Object v = entry.getValue();

if(null != v && !"".equals(v)

&& !"sign".equals(k) && !"key".equals(k)) {

sb.append(k + "=" + v + "&");

}

}

sb.append("key=" + WXConfig.APP_PERTNER_KEY);

System.out.println(sb.toString());

String sign = MD5Utils.MD5Encode(sb.toString(),"UTF-8").toUpperCase();

return sign;

}

public String create_nonce_str() {

String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

String res = "";

for (int i = 0; i < 32; i++) {

Random rd = new Random();

res += chars.charAt(rd.nextInt(chars.length() - 1));

}

return res;

}

3.IOS客户端开发

导入微信开发包

添加URL Types

在AppDelegate.m中注册应用

#import "AppDelegate.h"

#import "XSTabBarViewController.h"

#import

#import "WXApi.h"

@interface AppDelegate ()

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

// Override point for customization after application launch.

// [NSThread sleepForTimeInterval:2.0];

// 进入主控制器

self.window = [[UIWindow alloc] init];

self.window.frame = [UIScreen mainScreen].bounds;

self.window.rootViewController = [[XSTabBarViewController alloc] init];

[self.window makeKeyAndVisible];

//向微信注册应用。

[WXApi registerApp:@"wxfb96c2a9b531be26"];

return YES;

}

-(void) onResp:(BaseResp*)resp

{

// NSLog(@" ----onResp %@",resp);

/*

ErrCode ERR_OK = 0(用户同意)

ERR_AUTH_DENIED = -4(用户拒绝授权)

ERR_USER_CANCEL = -2(用户取消)

code 用户换取access_token的code,仅在ErrCode为0时有效

state 第三方程序发送时用来标识其请求的唯一性的标志,由第三方程序调用sendReq时传入,由微信终端回传,state字符串长度不能超过1K

lang 微信客户端当前语言

country 微信用户当前国家信息

*/

if ([resp isKindOfClass:[SendAuthResp class]]) //判断是否为授权请求,否则与微信支付等功能发生冲突

{

SendAuthResp *aresp = (SendAuthResp *)resp;

if (aresp.errCode== 0)

{

// NSLog(@"code %@",aresp.code);

[[NSNotificationCenter defaultCenter] postNotificationName:@"wechatDidLoginNotification" object:self userInfo:@{@"code":aresp.code}];

}

}else{ // 支付请求回调

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

NSString *strMsg = [NSString stringWithFormat:@"支付结果"];

NSString *respcode = @"0";

switch (resp.errCode) {

case WXSuccess:

strMsg = @"支付结果:成功!";

// NSLog(@"支付成功-PaySuccess,retcode = %d", resp.errCode);

respcode = @"1";

break;

default:

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

// NSLog(@"错误,retcode = %d, retstr = %@", resp.errCode,resp.errStr);

respcode = @"0";

break;

}

[[NSNotificationCenter defaultCenter] postNotificationName:@"wechatDidPayNotification" object:self userInfo:@{@"respcode":respcode}];

}

}

//iOS 9.0 之前的处理方法不保证正确,如有错误还望指正

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation

{

NSLog(@"iOS 9.0 之前");

return [self applicationOpenURL:url];

}

-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options {

NSLog(@"iOS 9.0 之后");

return [self applicationOpenURL:url];

}

- (BOOL)applicationOpenURL:(NSURL *)url

{

if([[url absoluteString] rangeOfString:@"wxfb96c2a9b531be26://pay"].location == 0){

return [WXApi handleOpenURL:url delegate:self];

}

if ([url.host isEqualToString:@"safepay"])

{

[[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:nil];

return YES;

}

return YES;

}

}

在需要支付的Controller中接受微信支付通知

- (void)viewDidLoad {

[super viewDidLoad];

// 接受微信支付通知

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(wechatDidPayNotification:) name:@"wechatDidPayNotification" object:nil];

}

向服务器端获取统一订单,并拉起微信进行支付

-(void)weixinPay

{

NSString *userUrlStr = [NSString stringWithFormat:@"%@?sid=%@&account=%@&desc=%@", WX_PREPAY_URL, self.student.sid,self.payJinE,self.student.nid];

NSURL *url = [NSURL URLWithString:userUrlStr];

// NSLog(@"userUrlStr = %@", userUrlStr);

NSURLRequest *request = [NSURLRequest requestWithURL:url];

AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]initWithRequest:request];

[MBProgressHUD showMessage:@"跳转中,请稍候"];

[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, NSDictionary *responseObject) {

[MBProgressHUD hideHUD];

// NSLog(@"微信支付的response = %@", operation.responseString);

NSData *JSONData = [operation.responseString dataUsingEncoding:NSUTF8StringEncoding];

NSDictionary *userDict = [NSJSONSerialization JSONObjectWithData:JSONData options:NSJSONReadingMutableLeaves error:nil];

// 调用微信支付

PayReq *request = [[PayReq alloc] init];

/** 商家向财付通申请的商家id */

request.partnerId = [userDict objectForKey:@"partnerid"];

/** 预支付订单 */

request.prepayId= [userDict objectForKey:@"prepayid"];

/** 商家根据财付通文档填写的数据和签名 */

request.package = [userDict objectForKey:@"package"];

/** 随机串,防重发 */

request.nonceStr= [userDict objectForKey:@"noncestr"];

/** 时间戳,防重发 */

request.timeStamp= [[userDict objectForKey:@"timestamp"] intValue];

/** 商家根据微信开放平台文档对数据做的签名 */

request.sign= [userDict objectForKey:@"sign"];

self.sign = request.sign;

self.ordnum = [userDict objectForKey:@"ordnum"];

[WXApi sendReq: request];

}failure:^(AFHTTPRequestOperation *operation, NSError *error) {

[MBProgressHUD hideHUD];

NSLog(@"发生错误!%@",error);

}];

NSOperationQueue *queue = [[NSOperationQueue alloc] init];

[queue addOperation:operation];

}

// 微信支付结果

-(void)wechatDidPayNotification:(NSNotification *)notification

{

// NSLog(@"wechatDidPayNotification");

NSDictionary *nameDictionary = [notification userInfo];

NSString *respcode = [nameDictionary objectForKey:@"respcode"];

if([respcode isEqualToString:@"1"]){

// 支付成功,更新用户信息

[self payDidFinish];

}else{

// 支付失败,

[self setupAlertControllerWithTitle:@"微信支付结果" messge:@"本次支付未完成,您可以稍后重试!" confirm:@"好的"];

}

}


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:怎么介绍接口自动化框架(接口自动化用例设计)
下一篇:自学接口测试应该怎么做(接口测试需要学什么)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~