您好,登錄后才能下訂單哦!
首先要弄個支付相關的類
@interface MOIPayModel : NSObject //channel :1:支付寶 2:微信 @property NSInteger channel; //支付金額 (分) @property float price; @property (strong , nonatomic) NSString *productName; //商品標題 @property (strong , nonatomic) NSString *productDescription; //商品描述 //后臺系統訂單ID @property (nonatomic) long long orderId; //支付寶屬性 /** PID */ @property (strong , nonatomic) NSString *partner; /** 收款支付寶賬號 */ @property (strong , nonatomic) NSString *seller; /** 私鑰 */ @property (strong , nonatomic) NSString *privateKey; /** 返回URL */ @property (strong , nonatomic) NSString *notifyURL; //微信支付屬性 /** 商戶ID */ @property (nonatomic, retain) NSString *partnerId; /** 預支付ID */ @property (nonatomic, retain) NSString *prepayId; /** 商戶密鑰 */ @property (nonatomic, retain) NSString *spKey; @end
先說下支付寶的支付流程吧,其實支付寶的并不需要什么動態信息,可以把所有的信息都寫在客戶端里,不過這樣很不安全,所以還是要向自己的服務器請求相關信息。
_MOIPayModel.notifyURL = @"返回URL"; _MOIPayModel.partner = @"PID"; _MOIPayModel.seller = @"收款支付寶賬號"; _MOIPayModel.privateKey = @"商戶密鑰";
typedef void(^MOIPayOderUtilCompletion)(MOIPayModel *payModel , id message); typedef void(^MOIPayOderUtilFailed)(MOIPayModel *payModel , id message); static NSString *appScheme = @"調用支付的app注冊在info.plist中的scheme"; -(void)goToAliPayFor:(MOIPayModel *)_payModel completion:(MOIPayOderUtilCompletion)_payCompletion failed:(MOIPayOderUtilFailed)_payFailed{ if (!_payModel.partner || !_payModel.seller || !_payModel.productName || !_payModel.notifyURL) { NSLog(@"缺少信息,支付將失敗"); } //將商品信息賦予AlixPayOrder的成員變量 Order *order = [[Order alloc] init]; order.partner = _payModel.partner; order.seller = _payModel.seller; order.tradeNO = _payModel.orderNO; //訂單ID(由商家自行制定) order.productName = _payModel.productName; //商品標題 order.productDescription = _payModel.productDescription; //商品描述 order.amount = [NSString stringWithFormat:@"%g",_payModel.price/100.f]; //商品價格 order.notifyURL = _payModel.notifyURL; //回調URL order.service = @"mobile.securitypay.pay"; order.paymentType = @"1"; order.inputCharset = @"utf-8"; order.itBPay = @"30m"; order.showUrl = @"m.alipay.com"; //將商品信息拼接成字符串 NSString *orderSpec = [order description]; //獲取私鑰并將商戶信息簽名,外部商戶可以根據情況存放私鑰和簽名,只需要遵循RSA簽名規范,并將簽名字符串base64編碼和UrlEncode id<DataSigner> signer = CreateRSADataSigner(_payModel.privateKey); NSString *signedString = [signer signString:orderSpec]; //將簽名成功字符串格式化為訂單字符串,請嚴格按照該格式 NSString *orderString = nil; if (signedString != nil) { orderString = [NSString stringWithFormat:@"%@&sign=\"%@\"&sign_type=\"%@\"",orderSpec, signedString, @"RSA"]; [[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) { int resultStatus = [resultDic intValueForKey:@"resultStatus"]; switch (resultStatus) { case 9000: _payCompletion(nil,nil); break; default: { _payFailed(nil,([resultDic safeObjectForKey:@"memo"] ? : @"支付中斷")); } break; } }]; }else{ _payFailed(nil,@"支付中斷"); } }
微信支付流程需要先拿到一個‘預支付id’,通常這個id是由后臺請求微信服務器得到的,具體的接口什么的我就不寫了,畢竟不是客戶端的事情。最后需要拿到幾個重要信息
_MOIPayModel.partnerId = @"商戶ID" _MOIPayModel.prepayId = @"預支付ID"; _MOIPayModel.spKey = @"商戶密鑰";
這三個重要信息都有了 把信息拼起來創建一個SIGN簽名 就可以向微信發請求了
PayReq *request = [[PayReq alloc] init]; request.partnerId = _payModel.partnerId; request.prepayId = _payModel.prepayId; request.package = @"Sign=WXPay"; //隨機串 request.nonceStr = [self ret32bitString]; NSDate *datenow = [NSDate date]; NSString *timeSp = [NSString stringWithFormat:@"%ld", (long)[datenow timeIntervalSince1970]]; UInt32 timeStamp =[timeSp intValue]; request.timeStamp= timeStamp; NSDictionary *_dic = @{@"appid":kWXAppID, @"partnerid":request.partnerId, @"prepayid":request.prepayId, @"package":request.package, @"noncestr":request.nonceStr, @"timestamp":@(request.timeStamp)//時間戳 }; request.sign = [self createMd5Sign:[_dic mutableCopy] spKey:_payModel.spKey]; if (![WXApi sendReq:request]) { NSLog(@"發起支付失敗"); }
回調結果
-(void) onResp:(BaseResp*)resp; { if ([resp isKindOfClass:[PayResp class]]){ PayResp*response=(PayResp*)resp; switch(response.errCode){ case WXSuccess: NSLog(@"微信支付成功"); break; case WXErrCodeUserCancel: NSLog(@"交易取消"); break; default: NSLog(@"支付失敗"); break; } } }
用到的一些方法
//創建sign簽名 - (NSString *)createMd5Sign:(NSMutableDictionary *)dict spKey:(NSString *)_spKey { NSMutableString *contentString =[NSMutableString string]; NSArray *keys = [dict allKeys]; //按字母順序排序 NSArray *sortedArray = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { return [obj1 compare:obj2 options:NSNumericSearch]; }]; //拼接字符串 for (NSString *categoryId in sortedArray) { if ( ![categoryId isEqualToString:@"sign"] && ![categoryId isEqualToString:@"key"] ) { [contentString appendFormat:@"%@=%@&", categoryId, [dict objectForKey:categoryId]]; } } //添加key字段 [contentString appendFormat:@"key=%@", _spKey]; //得到MD5 sign簽名 NSString *md5Sign =[self md5HexDigest:contentString]; return [md5Sign uppercaseString]; } //MD5 - (NSString *)md5HexDigest:(NSString*)password { if (!password || ![password isKindOfClass:[NSString class]] || password.length == 0) { return @""; } const char *original_str = [password UTF8String]; unsigned char result[CC_MD5_DIGEST_LENGTH]; CC_MD5(original_str, strlen(original_str), result); NSMutableString *hash = [NSMutableString string]; for (int i = 0; i < 16; i++) { [hash appendFormat:@"%02X", result[i]]; } NSString *mdfiveString = [hash lowercaseString]; return mdfiveString; } //隨機字符串 - (NSString *)ret32bitString { char data[32]; for (int x=0;x < 32;data[x++] = (char)('A' + (arc4random_uniform(26)))); return [[NSString alloc] initWithBytes:data length:32 encoding:NSUTF8StringEncoding]; }
當然了,這里不管是支付寶還是微信支付,成功也只是客戶端返回的成功,最保險的還是客戶端請求自己的服務器,在自己的服務器上確認支付真的已經成功了,再繼續業務流程,畢竟支付流程還是要謹慎一點的。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。