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

作者:只要你能好 时间:2021-12-24 14:16:43 

0.介绍预览

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

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

1.资料准备

1.1 账号注册

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

1.2 开发者认证

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

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

1.3 注册应用

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

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

2.Java后台开发

添加依赖


<!-- 微信支付依赖 -->
<dependency>
<groupId>org.xmlpull</groupId>
<artifactId>xmlpull</artifactId>
<version>1.1.3.1 </version>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.3</version>
<classifier>jdk15</classifier>
</dependency>
<!-- https://mvnrepository.com/artifact/com.thoughtworks.xstream/xstream -->
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.ning/async-http-client -->
<dependency>
<groupId>com.ning</groupId>
<artifactId>async-http-client</artifactId>
<version>1.8.13</version>
</dependency>


生成统一订单





@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<String, String> 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<String, String> genOrderData(HttpServletRequest request, String subject, String body,
         int acc, String appid, String out_trade_no)
  throws IOException, ExecutionException, InterruptedException, XmlPullParserException {
 SortedMap<String, String> paraMap = new TreeMap<String, String>();
 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<String, String> map = WXRequestUtil.doXMLParse(xmlStr);
  prepay_id = (String) map.get("prepay_id");
 }

SortedMap<String, String> payMap = new TreeMap<String, String>();
 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<String,String> parameters){
 String sign = "";
  StringBuffer sb = new StringBuffer();
  sb.append("<xml>");
  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("</xml>");
  return sb.toString();
 }

//生成签名
public String createSign(SortedMap<String,String> 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客户端开发

导入微信开发包

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

添加URL Types

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

在AppDelegate.m中注册应用


#import "AppDelegate.h"
#import "XSTabBarViewController.h"
#import <AlipaySDK/AlipaySDK.h>
#import "WXApi.h"

@interface AppDelegate ()<WXApiDelegate>

@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<UIApplicationOpenURLOptionsKey,id> *)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:@"好的"];
}
}

来源:https://blog.csdn.net/u012131769/article/details/76637890

标签:java,微信,APP
0
投稿

猜你喜欢

  • springboot中PostMapping正常接收json参数后返回404问题

    2021-07-22 20:46:28
  • 微信小程序与AspNetCore SignalR聊天实例代码

    2022-12-21 01:29:06
  • java实现选课系统

    2021-08-15 07:43:44
  • Android Studio实现带三角函数对数运算功能的高级计算器

    2022-08-21 05:02:47
  • MyBatis特殊字符转义拦截器问题针对(_、\\、%)

    2023-09-12 00:46:39
  • C#中Socket与Unity相结合示例代码

    2022-09-15 23:24:15
  • Java程序员应该遵守的10条纪律

    2022-07-16 22:47:41
  • Java结构型模式之门面模式详解

    2023-07-29 10:26:55
  • 使用纯Java实现一个WebSSH项目的示例代码

    2023-03-11 11:32:20
  • Java封装公共Result结果返回类的实现

    2023-06-17 08:47:47
  • C#/VB.NET实现HTML转为XML的示例代码

    2021-08-13 20:46:48
  • 如何在springboot中实现页面的国际化

    2021-08-13 03:33:07
  • 详解Java实践之建造者模式

    2023-01-14 23:03:13
  • JAVA实现简单系统登陆注册模块

    2021-11-05 05:41:50
  • C#使用linq语句查询数组中以特定字符开头元素的方法

    2022-09-22 06:39:07
  • Android编程实现手机自带内部存储路径的获取方法

    2022-05-14 11:59:11
  • Mybatis 入参类型方式全面详解

    2023-10-16 20:03:40
  • Java中joda日期格式化工具的使用示例

    2023-03-01 11:49:10
  • Mybatis利用OGNL表达式处理动态sql的方法教程

    2022-11-26 22:22:02
  • C#中ToString数据类型格式大全(千分符)

    2023-10-03 05:08:48
  • asp之家 软件编程 m.aspxhome.com