一、註冊登入微信開放平臺賬號
- 註冊登入微信開放平臺賬號
- 新增一個用於支付/分享的移動應用,等待稽核通過
- 前往管理中心-移動應用,為通過稽核的移動應用申請支付功能,並等待稽核通過
詳細步驟參照微信支付官方文件 微信APP支付接入商戶服務中心
二、整合微信SDK
-
前往微信資源中心下載 iOS 的 SDK,並新增到專案中
-
編輯
info.plist
,將微信新增到 APP 跳轉白名單 -
在
Targets-Info-URL Types
新增微信的 APP_ID -
在
AppDelegate
處理相關回撥(需要#import "WXApi.h"
)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 註冊(如果使用了友盟,則先註冊友盟)
[WXApi registerApp:@"wxd930ea5d5a258f4f"];
return YES;
}
- (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];
}
// 微信支付結果的回撥
- (void)onResp:(BaseResp *)resp {
//啟動微信支付的response
NSString *strMsg = [NSString stringWithFormat:@"errcode:%d", resp.errCode];
BOOL paySuccess = false;
if([resp isKindOfClass:[PayResp class]]){
//支付返回結果,實際支付結果需要去微信伺服器端查詢
switch (resp.errCode) {
case 0:
strMsg = @"支付結果:成功!";
paySuccess = true;
break;
case -1:
strMsg = @"支付結果:失敗!";
break;
case -2:
strMsg = @"使用者已經退出支付!";
break;
default:
strMsg = [NSString stringWithFormat:@"支付結果:失敗!retcode = %d, retstr = %@", resp.errCode,resp.errStr];
break;
}
}
NSNotification *nofity = [[NSNotification alloc] initWithName:kNofificationWechatPayCallback object:nil userInfo:@{@"success":paySuccess ? @(YES) : @(NO) ,@"errMsg":paySuccess ? @"" : strMsg}];
[[NSNotificationCenter defaultCenter] postNotification:nofity];
}
複製程式碼
- 伺服器呼叫統一下單介面,將關鍵引數返回
"appid": "wxb423c568326b71ee" // 微信開放平臺稽核通過的應用 APPID
"partnerId": "1326631501" // 微信支付分配的商戶號,也就是 MCH_ID
"nonceStr": "EStCEnC8lVvIBV10" // 隨機字串
"prepayId": "wx20160601113412a39d0f4d700072397236" // 預支付交易會話標識
複製程式碼
- 客戶端請求介面獲取引數,並簽名後調起微信
/** 微信支付 */
- (void)pay {
// 向伺服器傳送請求,獲取微信訂單資訊
NSURLSession *session = [NSURLSession sharedSession];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://www.xxx.com/pay.php"]];
request.HTTPMethod = @"POST";
NSURLSessionTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSDictionary *res = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
if ([res[@"errCode"] intValue] == 0) {
// 調起微信
PayReq *req = [[PayReq alloc] init];
req.partnerId = kWx_MchId;
req.prepayId = res[@"prepayId"];
req.nonceStr = res[@"nonce_str"];
req.timeStamp = (UInt32)[[NSDate date] timeIntervalSince1970];
req.package = @"Sign=WXPay";
// 傳入相關引數簽名
req.sign = [self getSign:@{
@"appid": kWx_AppId,
@"partnerid": req.partnerId,
@"noncestr": req.nonceStr,
@"package": req.package,
@"timestamp": @(req.timeStamp).stringValue,
@"prepayid": req.prepayId
}];
[WXApi sendReq:req];
}
}];
[task resume];
}
/**
生成簽名引數sign
@param params 引數
@return sign
*/
- (NSString *)getSign:(NSDictionary *)params {
NSMutableString *contentString =[NSMutableString string];
NSArray *keys = [params allKeys];
//按字母順序排序
NSArray *sortedArray = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [obj1 compare:obj2 options:NSNumericSearch];
}];
//拼接字串
for (NSString *categoryId in sortedArray) {
if (![[params objectForKey:categoryId] isEqualToString:@""]
&& ![categoryId isEqualToString:@"sign"]
&& ![categoryId isEqualToString:@"key"]
) {
[contentString appendFormat:@"%@=%@&", categoryId, [params objectForKey:categoryId]];
}
}
//新增key欄位
[contentString appendFormat:@"key=%@", kWx_PartnerKey];
//得到MD5 sign簽名
NSString *sign = [self getMD5:contentString];
return sign;
}
/**
MD5加密
@param sourceString 源字串
@return 加密後的字串
*/
- (NSString *)getMD5:(NSString *)sourceString {
NSData *data = [sourceString dataUsingEncoding:NSUTF8StringEncoding];
unsigned char result[CC_MD5_DIGEST_LENGTH];
CC_MD5(data.bytes, (CC_LONG)data.length, result);
return [NSString stringWithFormat:
@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
result[0], result[1], result[2], result[3],
result[4], result[5], result[6], result[7],
result[8], result[9], result[10], result[11],
result[12], result[13], result[14], result[15]
];
}
複製程式碼