兩個月前app中集成了微信支付功能,現(xiàn)在準(zhǔn)備看著項(xiàng)目中自己寫的代碼和之前參考的文章記錄下來,方便以后開發(fā)方便。之前是參考華之曦的文章履因。
1.準(zhǔn)備工作
先要在微信開放平臺注冊申請一個商戶號,好像是要300RMB盹愚,一般一到兩個禮拜栅迄,時間比較久,后臺弄的具體不是很清楚皆怕。
去微信公眾平臺下載微信SDK毅舆,將
1EF653AA-13F4-4C8E-8DC0-3A89FB44B169.png
這幾個拖到項(xiàng)目中去,readme可以不要(里面寫的是每個版本的修改什么的端逼,可以看一下)朗兵。將需要用上的庫導(dǎo)入
9C833149-1C8A-49A0-9F87-0E351700273E.png
(dylib的就是tbd的),具體流程還是不寫了吧顶滩,微信開放平臺——>資源中心>——接入指南——>iOS接入指南余掖,里面寫的很詳細(xì)了,在Info下面URL_type 添加url_scheme,填寫微信開放平臺注冊的APPID盐欺。
2.Appdelegate代碼
導(dǎo)入WXApi.h赁豆、WXApiObject頭文件,然后注冊
[WXApi registerApp:WX_AppID];
還有支付回調(diào)方法
-(void)onResp:(BaseResp *)resp {
if ([resp isKindOfClass:[PayResp class]]) {
PayResp*response=(PayResp*)resp; // 微信終端返回給第三方的關(guān)于支付結(jié)果的結(jié)構(gòu)體
switch (response.errCode) {
case WXSuccess:
{// 支付成功冗美,向后臺發(fā)送消息
NSLog(@"支付成功");
[[NSNotificationCenter defaultCenter] postNotificationName:@"WX_PaySuccess" object:nil];
}
break;
case WXErrCodeCommon:
{ //簽名錯誤魔种、未注冊APPID、項(xiàng)目設(shè)置APPID不正確粉洼、注冊的APPID與設(shè)置的不匹配节预、其他異常等
// [MBProgressHUD showError:@"支付失敗"];
NSLog(@"支付失敗");
}
break;
case WXErrCodeUserCancel:
{ //用戶點(diǎn)擊取消并返回
NSLog(@"取消支付");
// [MBProgressHUD showError:@"取消支付"];
}
break;
case WXErrCodeSentFail:
{ //發(fā)送失敗
NSLog(@"發(fā)送失敗");
// [MBProgressHUD showError:@"發(fā)送失敗"];
}
break;
case WXErrCodeUnsupport:
{ //微信不支持
NSLog(@"微信不支持");
// [MBProgressHUD showError:@"微信不支持"];
}
break;
case WXErrCodeAuthDeny:
{ //授權(quán)失敗
NSLog(@"授權(quán)失敗");
// [MBProgressHUD showError:@"授權(quán)失敗"];
}
break;
default:
break;
}
}
}
-(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];
}
3.調(diào)起支付的頁面
將這幾個用宏定義
9E3B264C-8D16-4BEC-BBE0-5731839EABFE.png
還有獲取ip、轉(zhuǎn)換xml字符創(chuàng)属韧、簽名加密都是用的華之曦的工具類安拟,哈哈哈,這宵喂。糠赦。。锅棕。全是竊取別人的現(xiàn)有成果啊拙泽,好尷尬。哈哈哈
然后就是喚起支付的按鈕點(diǎn)擊事件了裸燎,還是看代碼
-(void)payClicked{
NSString *appid,*mch_id,*nonce_str,*sign,*body,*out_trade_no,*total_fee,*spbill_create_ip,*notify_url,*trade_type,*partner;
//應(yīng)用APPID
appid = WX_AppID;
//微信支付商戶號
mch_id = MCH_ID;
//產(chǎn)生隨機(jī)字符串
nonce_str = [self generateTradeNO];
body = _dic[@"xxx"];
//訂單號
out_trade_no = _dic[@"xxx"];
//交易金額 交易金額1表示0.01顾瞻,所以乘100
total_fee = @([_dic[@"xxx"]floatValue]*100).stringValue;
//獲取本機(jī)ip 這個就要用到工具類了
spbill_create_ip = [getIPhoneIP getIPAddress];
//交易通知網(wǎng)站 問下后臺
notify_url = @"xxxxxxxxx";
trade_type = @"APP";
partner = WX_ParterKey;
//簽名 也是工具類
DataMD5 *data = [[DataMD5 alloc]initWithAppid:appid mch_id:mch_id nonce_str:nonce_str partner_id:partner body:body out_trade_no:out_trade_no total_fee:total_fee spbill_create_ip:spbill_create_ip notify_url:notify_url trade_type:trade_type];
sign = [data getSignForMD5];
NSMutableDictionary *dic = [NSMutableDictionary dictionary];
[dic setValue:appid forKey:@"appid"];//公眾賬號ID
[dic setValue:mch_id forKey:@"mch_id"];//商戶號
[dic setValue:nonce_str forKey:@"nonce_str"];//隨機(jī)字符串
[dic setValue:sign forKey:@"sign"];//簽名
[dic setValue:body forKey:@"body"];//商品描述
[dic setValue:out_trade_no forKey:@"out_trade_no"];//訂單號
[dic setValue:total_fee forKey:@"total_fee"];//金額
[dic setValue:spbill_create_ip forKey:@"spbill_create_ip"];//終端IP
[dic setValue:notify_url forKey:@"notify_url"];//通知地址
[dic setValue:trade_type forKey:@"trade_type"];//交易類型
// 轉(zhuǎn)換成xml字符串
NSString *string = [dic XMLString];
[self http:string];
}
#pragma mark - 拿到轉(zhuǎn)換好的xml發(fā)送請求
- (void)http:(NSString *)xml {
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
MBProgressHUD *_hud = [MBProgressHUD showHUDAddedTo:delegate.window animated:YES];
_hud.labelText = @"正在獲取支付訂單...";
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//這里傳入的xml字符串只是形似xml,但是不是正確是xml格式德绿,需要使用af方法進(jìn)行轉(zhuǎn)義
manager.responseSerializer = [[AFHTTPResponseSerializer alloc] init];
[manager.requestSerializer setValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
//這個是統(tǒng)一下單那個api
[manager.requestSerializer setValue:@"https://api.mch.weixin.qq.com/pay/unifiedorder" forHTTPHeaderField:@"SOAPAction"];
[manager.requestSerializer setQueryStringSerializationWithBlock:^NSString *(NSURLRequest *request, NSDictionary *parameters, NSError *__autoreleasing *error) {
return xml;
}];
//發(fā)起請求
[manager POST:@"https://api.mch.weixin.qq.com/pay/unifiedorder" parameters:xml progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSString *responseString = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding] ;
NSLog(@"responseString is %@",responseString);
//將微信返回的xml數(shù)據(jù)解析轉(zhuǎn)義成字典
NSDictionary *dic = [NSDictionary dictionaryWithXMLString:responseString];
//判斷返回的許可
if ([[dic objectForKey:@"result_code"] isEqualToString:@"SUCCESS"] &&[[dic objectForKey:@"return_code"] isEqualToString:@"SUCCESS"] ) {
//發(fā)起微信支付朋其,設(shè)置參數(shù)
PayReq *request = [[PayReq alloc] init];
request.openID = [dic objectForKey:@"appid"];
request.partnerId = [dic objectForKey:@"mch_id"];
request.prepayId= [dic objectForKey:@"prepay_id"];
request.package = @"Sign=WXPay";
request.nonceStr= [dic objectForKey:@"nonce_str"];
//將當(dāng)前事件轉(zhuǎn)化成時間戳
NSDate *datenow = [NSDate date];
NSString *timeSp = [NSString stringWithFormat:@"%ld", (long)[datenow timeIntervalSince1970]];
UInt32 timeStamp =[timeSp intValue];
request.timeStamp = timeStamp;
// 簽名加密
DataMD5 *md5 = [[DataMD5 alloc] init];
request.sign=[md5 createMD5SingForPay:request.openID partnerid:request.partnerId prepayid:request.prepayId package:request.package noncestr:request.nonceStr timestamp:request.timeStamp];
// 調(diào)用微信
[WXApi sendReq:request];
// [MBProgressHUD hideHUD];
}else{
// LXLog(@"參數(shù)不正確,請檢查參數(shù)");
// [MBProgressHUD hideHUD];
// [MBProgressHUD showError:@"支付錯誤脆炎!"];
_hud.labelText = @"支付錯誤!";
}
[_hud hide:YES afterDelay:0.5];
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
_hud.labelText = @"請檢查網(wǎng)絡(luò)連接";
[_hud hide:YES afterDelay:0.5];
}];
}
- (NSString *)generateTradeNO {
static int kNumber = 15;
NSString *sourceStr = @"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
NSMutableString *resultStr = [[NSMutableString alloc] init];
srand((unsigned)time(0));
for (int i = 0; i < kNumber; i++) {
unsigned index = rand() % [sourceStr length];
NSString *oneStr = [sourceStr substringWithRange:NSMakeRange(index, 1)];
[resultStr appendString:oneStr];
}
return resultStr;
}
-(void)paysuccess{
for (UIViewController *temp in self.navigationController.viewControllers) {
if ([temp isKindOfClass:[要跳轉(zhuǎn)的頁面 class]])
{
[self.navigationController popToViewController:temp animated:YES];
}
}
}
-(void)dealloc{
[[NSNotificationCenter defaultCenter]removeObserver:self];
}
因?yàn)閍ppdelegate里面支付回調(diào)里支付成功發(fā)送通知了氓辣,這里監(jiān)聽通知做處理秒裕,dealloc刪除。
DataMD5這個工具類中要拼接商戶密匙
2DB17843-0F5E-4FE3-91B3-1D0B80AD3144.png
好像就這樣了钞啸,還是要多看官方SDK吧几蜻,之前看集成教程都是看不懂的,看了官方SDK之后再看教程就好了体斩。記錄下來加深一下印象