0.介紹預覽
針對需要在IOS手機上接入原生微信支付場景,調用微信進行支付。如圖:


1.資料準備
1.1 賬號注冊
打開https://open.weixin.qq.com,注冊微信開放平臺開發者賬號
1.2 開發者認證
登錄,進入賬號中心,進行開發者資質認證。

1.3 注冊應用
認證完成后,進入管理中心,新建移動應用。填寫應用資料,其中android版應用簽名可通過掃碼安裝溫馨提供的應用獲得,詳細參考微信文檔。創建完成后點擊查看,申請開通微信支付。一切準備就緒!

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客戶端開發
導入微信開發包

添加URL Types

在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:@"好的"];
}
}
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。