這篇文章主要介紹了iOS如何實(shí)現(xiàn)微信支付流程,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
員工經(jīng)過長(zhǎng)期磨合與沉淀,具備了協(xié)作精神,得以通過團(tuán)隊(duì)的力量開發(fā)出優(yōu)質(zhì)的產(chǎn)品。創(chuàng)新互聯(lián)公司堅(jiān)持“專注、創(chuàng)新、易用”的產(chǎn)品理念,因?yàn)椤皩W⑺詫I(yè)、創(chuàng)新互聯(lián)網(wǎng)站所以易用所以簡(jiǎn)單”。公司專注于為企業(yè)提供網(wǎng)站建設(shè)、成都網(wǎng)站建設(shè)、微信公眾號(hào)開發(fā)、電商網(wǎng)站開發(fā),成都微信小程序,軟件按需策劃設(shè)計(jì)等一站式互聯(lián)網(wǎng)企業(yè)服務(wù)。
配置
1.微信支付需要兩個(gè)賬號(hào),財(cái)付通和微信開發(fā)者,注冊(cè)完成后需要開通支付功能,這些流程就不用多說了。在所有申請(qǐng)成功后,我們要取出我們支付功能需要的key:
appID、app密鑰(微信發(fā)給你的郵件中有如何生成密鑰的鏈接)、商戶號(hào)。
2.在Xcode中配置app ID,需要設(shè)置下白名單,在url中配置app ID,不清楚的童鞋可以百度一下。
支付
從此處開始,進(jìn)入本次的主題,開始支付。支付的過程且分為四個(gè)步驟:
第一步 獲取訂單號(hào)
獲取訂單號(hào)的途徑可以是客戶端自己生成,也可以去服務(wù)器生成,不過一般都是服務(wù)器生成。假設(shè)拿到了訂單號(hào)設(shè)為order_no。
第二步 統(tǒng)一下單
這個(gè)過程是非常關(guān)鍵的一步,也是坑常駐的一步。統(tǒng)一下單有的人做法是在服務(wù)器操作,有的在客戶端,不管在哪下單都是有必要搞懂的。接下來看看統(tǒng)一下單必須要的參數(shù)列表:
/*應(yīng)用ID 微信開放平臺(tái)審核通過的應(yīng)用app ID*/ @property (nonatomic, copy) NSString *appid; /*商戶號(hào) 微信支付分配的商戶號(hào)*/ @property (nonatomic, copy) NSString *mch_id; /*隨機(jī)字符串 隨機(jī)字符串,不長(zhǎng)于32位*/ @property (nonatomic, copy) NSString *nonce_str; /*簽名*/ @property (nonatomic, copy) NSString *sign; /*商品描述 天天愛消除-游戲充值。*/ @property (nonatomic, copy) NSString *body; /*商戶訂單號(hào)*/ @property (nonatomic, copy) NSString *out_trade_no; /*總金額 訂單總金額,單位為分*/ @property (nonatomic, copy) NSString *total_fee; /*終端IP*/ @property (nonatomic, copy) NSString *spbill_create_ip; /*通知地址*/ @property (nonatomic, copy) NSString *notify_url; /*交易類型*/ @property (nonatomic, copy) NSString *trade_type;
其中,sign是其他所有參數(shù)按照key1=value1&key2=value2...的方式拼接,然后進(jìn)行加密得到。參數(shù)拼接按照字母排序,舉個(gè)例子,參數(shù)為appid=@"id",mch_id=@"mch"得到的字符串應(yīng)該是:@"appid=id&mch_id=mch",然后對(duì)該字符串進(jìn)行加密,如下述代碼
- (instancetype)initWithDicInfo:(NSDictionary *)infoDic{ if (self = [super init]) { self.appid = WECHAT_SHARE_APPID; self.mch_id = WECHAT_MCH_ID; self.nonce_str = [AppMethod getRandomString]; self.body = @"test"; self.out_trade_no = [infoDic formateObjectForKey:@"order_no"]; self.total_fee = [NSString stringWithFormat:@"%@", [infoDic formateObjectForKey:@"amount"]]; self.spbill_create_ip = [AppMethod deviceIPAdress]; self.notify_url = [NSString stringWithFormat:@"%@%@", BASE_URL, WECHAT_NOTI_URL]; self.trade_type = @"APP"; self.payDic = [NSMutableDictionary dictionary]; [self.payDic setValue:self.appid forKey:@"appid"]; [self.payDic setValue:self.mch_id forKey:@"mch_id"]; [self.payDic setValue:self.nonce_str forKey:@"nonce_str"]; [self.payDic setValue:self.body forKey:@"body"]; [self.payDic setValue:self.out_trade_no forKey:@"out_trade_no"]; [self.payDic setValue:self.total_fee forKey:@"total_fee"]; [self.payDic setValue:self.spbill_create_ip forKey:@"spbill_create_ip"]; [self.payDic setValue:self.notify_url forKey:@"notify_url"]; [self.payDic setValue:self.trade_type forKey:@"trade_type"]; self.sign = [self partnerSignOrder:self.payDic]; [self.payDic setValue:self.sign forKey:@"sign"]; } return self; } - (NSString *)partnerSignOrder:(NSDictionary*)paramDic{ NSArray *keyArray = [paramDic allKeys]; NSMutableArray *sortedKeyArray = [NSMutableArray arrayWithArray:keyArray]; [sortedKeyArray sortUsingComparator:^NSComparisonResult(NSString* key1, NSString* key2) { return [key1 compare:key2]; }]; NSMutableString *paramString = [NSMutableString stringWithString:@""]; // 拼接成 A=B&X=Y for (NSString *key in sortedKeyArray){ if ([paramDic[key] length] != 0){ [paramString appendFormat:@"&%@=%@", key, paramDic[key]]; } } if ([paramString length] > 1){ [paramString deleteCharactersInRange:NSMakeRange(0, 1)]; // remove first '&' } [paramString appendFormat:@"&key=%@", WeChatPARTNER_ID];//app密鑰 return [[AppMethod signString:paramString] uppercaseString]; } AppMethod.m + (NSString *)signString:(NSString*)origString{ const char *original_str = [origString UTF8String]; unsigned char result[32]; CC_MD5(original_str, (CC_LONG)strlen(original_str), result);//調(diào)用md5 NSMutableString *hash = [NSMutableString string]; for (int i = 0; i < 16; i++){ [hash appendFormat:@"%02X", result[i]]; } return hash; }
這樣,統(tǒng)一下單的參數(shù)已經(jīng)準(zhǔn)備好了,下面開始請(qǐng)求微信的下單接口:https://api.mch.weixin.qq.com/pay/unifiedorder,現(xiàn)在坑又來了。按照微信的下單說明,傳給微信服務(wù)器的參數(shù)必須是XML格式的數(shù)據(jù)。如果你傳過這種類型的自然好辦,不過我猜大多數(shù)童鞋沒有傳過這種類型的數(shù)據(jù),好在AF有提供方法,不然就等著哭吧。繼續(xù)看代碼
+ (void)postWechatPayWithUrl:(NSString *)url params:(id)params andSuccess:(requestSuccessResult)successBlock andFailure:(requestFailureResult)failureBlock{ NSString *string = [params XMLString];//這里需要導(dǎo)入XMLDictionary文件,里面有該方法 AFHTTPSessionManager *session = [AFHTTPSessionManager manager]; // 這里傳入的XML字符串只是形似XML,但不是正確是XML格式,需要使用AF方法進(jìn)行轉(zhuǎn)義 session.responseSerializer = [[AFHTTPResponseSerializer alloc] init]; [session.requestSerializer setValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; [session.requestSerializer setValue:url forHTTPHeaderField:@"SOAPAction"]; [session.requestSerializer setQueryStringSerializationWithBlock:^NSString *(NSURLRequest *request, NSDictionary *parameters, NSError *__autoreleasing *error) { return string; }]; [session POST:url parameters:params progress:^(NSProgress * _Nonnull uploadProgress) { } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { successBlock(responseObject); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { HPError *hpError = [HPError errorWithCode:error.code desc:error.description]; failureBlock(hpError); }]; }
按照上述的步驟,到這里就可以正常下單了,如果微信服務(wù)器返回給你的數(shù)據(jù)中有"result_code" = SUCCESS; "return_code" = SUCCESS,說明下單成功,這個(gè)步驟也到此結(jié)束。
第三步 調(diào)起微信客戶端,并完成支付
如果第二步正常下單,那么微信會(huì)返回給你預(yù)支付ID,這個(gè)ID在最后的支付中至關(guān)重要,下面的代碼是比較統(tǒng)一的,大家都這么寫。
HPWechatProduct *product = [[HPWechatProduct alloc] initWithDic:result]; PayReq *req = [[PayReq alloc] init]; req.partnerId = product.partnerid; req.prepayId = product.prepayid; req.nonceStr = product.noncestr; req.timeStamp = [product.timestamp intValue]; req.package = product.package; req.sign = product.sign; BOOL flag = [WXApi sendReq:req]; HPWechatProduct.m - (instancetype)initWithDic:(NSDictionary *)dic{ if (self = [super init]) { self.appid = WECHAT_SHARE_APPID; self.partnerid = mah_id; self.prepayid = [dic formateObjectForKey:@"prepay_id"]; self.package = @"Sign=WXPay"; self.noncestr = [AppMethod getRandomString]; self.timestamp = [self getTime]; NSMutableDictionary *dic = [NSMutableDictionary dictionary]; [dic setValue:self.appid forKey:@"appid"]; [dic setValue:self.partnerid forKey:@"partnerid"]; [dic setValue:self.prepayid forKey:@"prepayid"]; [dic setValue:self.package forKey:@"package"]; [dic setValue:self.noncestr forKey:@"noncestr"]; [dic setValue:self.timestamp forKey:@"timestamp"]; self.sign = [self partnerSignOrder:dic]; } return self; } - (NSString *)partnerSignOrder:(NSDictionary*)paramDic{ NSArray *keyArray = [paramDic allKeys]; NSMutableArray *sortedKeyArray = [NSMutableArray arrayWithArray:keyArray]; [sortedKeyArray sortUsingComparator:^NSComparisonResult(NSString* key1, NSString* key2) { return [key1 compare:key2]; }]; NSMutableString *paramString = [NSMutableString stringWithString:@""]; // 拼接成 A=B&X=Y for (NSString *key in sortedKeyArray){ if ([paramDic[key] length] != 0){ [paramString appendFormat:@"&%@=%@", key, paramDic[key]]; } } if ([paramString length] > 1){ [paramString deleteCharactersInRange:NSMakeRange(0, 1)]; // remove first '&' } [paramString appendFormat:@"&key=%@", WeChatPARTNER_ID]; return [[AppMethod signString:paramString] uppercaseString]; } - (NSString *)getTime{ NSTimeInterval interval = [[NSDate date] timeIntervalSince1970]; return [NSString stringWithFormat:@"%ld", (long)interval]; } AppMethod.m + (NSString *)getRandomString { NSString *str = [NSString stringWithFormat:@"%s",genRandomString(32)]; return str; }
如果到了這一步,而且跑到了微信并完成了支付,那么微信會(huì)有一個(gè)回調(diào),告訴你支付成功了。然而真的成功了嘛,請(qǐng)繼續(xù)看第四步。
第四步 去服務(wù)器查詢是否支付成功
即使微信告訴你支付成功了,你也不能相信,只有錢真正打到你們的賬號(hào)里面了,才算支付成功。任何時(shí)候都不能以微信的回調(diào)的值判斷支付是否成功(這是微信文檔說的)。
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“iOS如何實(shí)現(xiàn)微信支付流程”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來學(xué)習(xí)!
文章名稱:iOS如何實(shí)現(xiàn)微信支付流程
路徑分享:http://aaarwkj.com/article28/iipocp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供建站公司、網(wǎng)站設(shè)計(jì)公司、網(wǎng)站導(dǎo)航、面包屑導(dǎo)航、企業(yè)建站、微信公眾號(hào)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)