公司须要到微信开放品台进行申请app支付功能 , 得到appid和微信支付商户号(mch_id)和API秘钥(key) 、 Appsecret(secret),开发中用到的,很重要html
• appid:appid是微信公众帐号或开放平台APP的惟一标识,在公众平台申请公众帐号或者在开放平台申请APP帐号后,微信会自动分配对应的appid,用于标识该应用。可json
在微信公众平台-->开发者中心查看,商户的微信支付审核经过邮件中也会包含该字段值。安全
• 微信支付商户号:商户申请微信支付后,由微信支付分配的商户收款帐号。服务器
• API密钥: 交易过程生成签名的密钥,仅保留在商户系统和微信支付后台,不会在网络中传播。商户妥善保管该Key,切勿在网络中传输,不能在其余客户端中存储,保证微信
key不会被泄漏。商户可根据邮件提示登陆微信商户平台进行设置。也可按一下路径设置:微信商户平台(pay.weixin.qq.com)-->帐户设置-->API安全-->密钥设置网络
• App secret : AppSecret是APPID对应的接口密码,用于获取接口调用凭证access_token时使用。微信开发
项目-->Info-->RUL Types,添加一个URL SChemes,内容为本身商户的APPID,以下图:app
步骤1:用户在商户APP中选择商品,提交订单,选择微信支付。微信公众平台
步骤2:商户后台收到用户支付单,调用微信支付统一下单接口。ide
步骤3:统一下单接口返回正常的prepay_id,再按签名规范从新生成签名后,将数据传输给APP。参与签名的字段名为appId,partnerId,prepayId,nonceStr,timeStamp,package。
注意:package的值格式为Sign=WXPay
步骤4:商户APP调起微信支付。
步骤5:商户后台接收支付通知。
步骤6:商户后台查询支付结果。
请求后台接口,获取调取微信支付所需的关键参数:partnerid、prepayid、package、sign、timestamp、noncestr
[WXApi registerApp:self.wxAppID];//与URL Type中设置的保持一致
request.openID = self.wxAppKey; request.partnerId = parterId; request.prepayId = prePayId; request.package = package; request.nonceStr = nonceStr; request.timeStamp = [timestamp intValue]; request.sign = sign;
if (![WXApi sendReq:request]) {
//微信调起支付失败
}
-(void)onResp:(BaseResp*)resp{ if ([respisKindOfClass:[PayRespclass]]){ PayResp*response=(PayResp*)resp; switch(response.errCode){ caseWXSuccess: //服务器端查询支付通知或查询API返回的结果再提示成功 NSlog(@"支付成功"); break; default: NSlog(@"支付失败,retcode=%d",resp.errCode); break; } } }
这里设置的URL Scheme必须与payOrder方法中的Scheme保持一致
在info.plist 文件中以下设置
这一步能够经过后台生成订单,直接返回订单字符串,或者移动端本身实例化一个订单对象,并生成订单字符串
//将商品信息赋予AlixPayOrder的成员变量 Order *order = [[Order alloc] init]; order.partner = partner; order.seller = seller; order.tradeNO = @"123456"; //订单ID(由商家自行制定) order.productName = @"太空杯"; //商品标题 order.productDescription = @"耐摔的太空杯"; //商品描述 order.amount = [NSString stringWithFormat:@"%.2f",0.01]; //商品价格 order.notifyURL = @"http://www.lanou3g.com"; //回调URL order.service = @"mobile.securitypay.pay"; order.paymentType = @"1"; order.inputCharset = @"utf-8"; order.itBPay = @"30m"; order.showUrl = @"m.alipay.com"; //应用注册scheme,在AlixPayDemo-Info.plist定义URL types NSString *appScheme = @"xiaohange"; //将商品信息拼接成字符串 NSString *orderSpec = [order description]; NSLog(@"orderSpec = %@",orderSpec); //获取私钥并将商户信息签名,外部商户能够根据状况存放私钥和签名,只须要遵循RSA签名规范,并将签名字符串base64编码和UrlEncode id<DataSigner> signer = CreateRSADataSigner(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) { // NSLog(@"reslut = %@",resultDic); //}]; }
b.调起支付宝支付
[[AlipaySDK defaultService] payOrder:orderString fromScheme:@"669SDKAliPay" callback:^(NSDictionary *dict) { if (dict) { NSLog(@"%@",dict); NSInteger statusCode = [dict[@"resultStatus"] integerValue]; NSString *msg = [NSString stringValue:dict[@"memo"]]; if (statusCode == 9000) { [self performSelector:@selector(paymentSuccess) withObject:self.tradeNo afterDelay:0.25f]; } else if (statusCode == 6001) { [self performSelector:@selector(paymentCancel) withObject:self.tradeNo afterDelay:0.25f]; } else { [self performSelector:@selector(paymentErrorWithMessage:) withObject:msg afterDelay:0.25f]; } } }];
#import <Foundation/Foundation.h> #import <UIKit/UIKit.h> #import "WXApi.h" #import <AlipaySDK/AlipaySDK.h> @protocol WanPaymentDataDelegate <NSObject> @optional - (void)paymentSuccess; - (void)paymentCancel; - (void)paymentResultWithError:(NSError *)error; @end typedef NS_OPTIONS(NSUInteger, WanPaymentType) { WanPaymentTypeAliPay = 2, //支付宝钱包 WanPaymentTypeWXPay = 1, //微信支付 WanPaymentTypeAliPayWAP = 102 //支付宝 WAP }; @interface WanPaymentData : NSObject <WXApiDelegate> { } @property (nonatomic, assign) WanPaymentType paymentType; @property (nonatomic, weak) id<WanPaymentDataDelegate> delegate; @property (nonatomic, weak) UIView *view; @property (nonatomic, copy) NSString *wxAppKey; @property (nonatomic, retain) NSString *tradeNo; //订单编号 @property (nonatomic, retain) NSString *paymentTradeNo; //支付编号 - 支付宝给的 @property (nonatomic, retain) NSString *productName; //订单名称 @property (nonatomic, retain) NSString *productDesc; //订单描述 @property (nonatomic, retain) NSString *productAmount; //订单单价 @property (nonatomic, retain) NSString *productEndTime; //订单结束时间 + (instancetype)instance; + (BOOL)canOpenPaymentApp:(WanPaymentType)paymentType; - (void)requestPaymentURLWithResult:(NSDictionary *)dict; - (void)paymentErrorWithMessage:(NSString *)errorMessage; - (BOOL)handleOpenURL:(NSURL *)url; //支付宝客户端回调 - (void)wxpayResultCode:(int)resultCode; //微信支付客户端回调 @end
#import "WanPaymentData.h" #import "NSString+Util.h" #import "AlixPayResult.h" //#import "PPUIUtils.h" //#import "UPPayPlugin.h" #import <YRJSONAdapter.h> #import "WanPayServer.h" #import "WanProgressHUD.h" static NSString *kPPPaymentURLForAliPay = @"alipay://alipayclient/"; static NSString *kPPGetPaymentURL = @"payment-pay/paySubmit"; static NSString *kPPPaymentParamAliPayClient = @"alipay_sdk"; //支付宝钱包 static NSString *kPPPaymentParamAliPayWAP = @"alipay_wap"; //支付宝网页 static NSString *kPPPaymentParamWXPayClient = @"wechat_sdk"; //微信客户端 #define kWeiXinWanAppKey @"wxb68956c81f8a2512" typedef NS_OPTIONS(NSUInteger, PPPaymentWCheckStatus) { PPPaymentCheckStatusOK = 1, //能够支付 PPPaymentCheckStatusAppNotInstalled = 2, //应用未安装 PPPaymentCheckStatusSignError = 3 //签名错误 }; @interface WanPaymentData () { WanPayServer *_payServer; } @end @implementation WanPaymentData + (instancetype)instance { static WanPaymentData *sharedInstance = nil; if (sharedInstance == nil) { sharedInstance = [[WanPaymentData alloc] init]; } return sharedInstance; } #pragma mark - Init #pragma mark - Class Method + (BOOL)canOpenPaymentApp:(WanPaymentType)paymentType { if (paymentType == WanPaymentTypeAliPay) { return [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:kPPPaymentURLForAliPay]]; } else if (paymentType == WanPaymentTypeWXPay) { return [WXApi isWXAppInstalled]; } return NO; } #pragma mark - Request Payment URL - (void)requestPaymentURLWithResult:(NSDictionary *)dict { [WanProgressHUD hideAfterDelay:1.5]; NSInteger resultCode = [[NSString stringValue:dict[@"state"][@"code"]] integerValue]; NSString *resultMsg = [NSString stringValue:dict[@"state"][@"msg"]]; if (resultCode == 1) { if (self.paymentType == WanPaymentTypeAliPay) { NSString *paymentURL = [NSString stringValue:dict[@"data"][@"pay_info"]]; NSString *clientFlag = [NSString stringValue:dict[@"data"][@"order_no"]]; [self openAliPayClientWithPaymentURL:paymentURL clientFlag:clientFlag]; } else if (self.paymentType == WanPaymentTypeAliPayWAP) { NSString *paymentURL = [NSString stringValue:[dict valueForKeyPath:@"data.payment_url"]]; NSString *htmlCode = [NSString stringValue:[dict valueForKeyPath:@"data.payment_html"]]; NSDictionary *param = @{@"title" : @"支付宝网页支付", @"URL" : paymentURL, @"html" : htmlCode}; // [[NSNotificationCenter defaultCenter] postNotificationName:LMBNotificationKeyForShowPaymentWebPage object:param userInfo:nil]; } else if (self.paymentType == WanPaymentTypeWXPay) { // NSString *jsonString = [NSString stringValue:[dict valueForKeyPath:@"data.payment_wx"]]; // NSDictionary *param = [jsonString objectFromJSONString]; [self openWXClientWithPaymentURL:dict[@"data"][@"pay_info"]]; } }else{ [self paymentErrorWithMessage:resultMsg]; } } #pragma mark - Interface Method
//- (void)paymentWithType:(WanPaymentType)type
//{
// self.paymentType = type;
//
// if (self.paymentType == WanPaymentTypeAliPay) {
// NSMutableDictionary *params = [NSMutableDictionary dictionary];
// [params setObject:kPPPaymentParamAliPayClient forKey:@"payment_type"];
// [params setObject:self.tradeNo forKey:@"order_sn"];
// [self requestPaymentURLWithParam:[NSDictionary dictionaryWithDictionary:params]];
// }
// else if (self.paymentType == WanPaymentTypeAliPayWAP) {
// NSMutableDictionary *params = [NSMutableDictionary dictionary];
// [params setObject:kPPPaymentParamAliPayWAP forKey:@"payment_type"];
// [params setObject:self.tradeNo forKey:@"order_sn"];
// [self requestPaymentURLWithParam:[NSDictionary dictionaryWithDictionary:params]];
// }
// else if (self.paymentType == WanPaymentTypeWXPay) {
// NSMutableDictionary *params = [NSMutableDictionary dictionary];
// [params setObject:kPPPaymentParamWXPayClient forKey:@"payment_type"];
// [params setObject:self.tradeNo forKey:@"order_sn"];
// [self requestPaymentURLWithParam:[NSDictionary dictionaryWithDictionary:params]];
// }
//}
#pragma mark - Handler Method - (void)openAliPayClientWithPaymentURL:(NSString *)paymentURL clientFlag:(NSString *)clientFlag { [[AlipaySDK defaultService] payOrder:paymentURL fromScheme:@"669SDKAliPay" callback:^(NSDictionary *dict) { if (dict) { NSLog(@"%@",dict); NSInteger statusCode = [dict[@"resultStatus"] integerValue]; NSString *msg = [NSString stringValue:dict[@"memo"]]; if (statusCode == 9000) { [self performSelector:@selector(paymentSuccess) withObject:self.tradeNo afterDelay:0.25f]; } else if (statusCode == 6001) { [self performSelector:@selector(paymentCancel) withObject:self.tradeNo afterDelay:0.25f]; } else { [self performSelector:@selector(paymentErrorWithMessage:) withObject:msg afterDelay:0.25f]; } } }]; } //- (void)openUPMPClientWithPaymentSN:(NSString *)paymentSN //{ // UIViewController *controller = [[[UIApplication sharedApplication] keyWindow] rootViewController]; // // if (![UPPayPlugin startPay:paymentSN mode:@"00" viewController:controller delegate:self]) { // [self paymentErrorWithMessage:@"抱歉,没法加载银联控件,请关闭应用重试!"]; // } //} - (void)openWXClientWithPaymentURL:(NSDictionary *)paymentParams { NSString *parterId = [NSString stringValue:[paymentParams valueForKey:@"partnerid"]]; NSString *prePayId = [NSString stringValue:[paymentParams valueForKey:@"prepayid"]]; NSString *package = [NSString stringValue:[paymentParams valueForKey:@"package"]]; NSString *sign = [NSString stringValue:[paymentParams valueForKey:@"sign"]]; NSString *timestamp = [NSString stringValue:[paymentParams valueForKey:@"timestamp"]]; NSString *nonceStr = [NSString stringValue:[paymentParams valueForKey:@"noncestr"]]; self.wxAppKey = [NSString stringValue:[paymentParams valueForKey:@"appid"]]; if ([NSString isEmpty:parterId] || [NSString isEmpty:prePayId] || [NSString isEmpty:package] || [NSString isEmpty:sign] || [NSString isEmpty:timestamp] || [NSString isEmpty:nonceStr]) { [self paymentErrorWithMessage:@"缺乏关键参数,没法执行微信支付!"]; return; } [WXApi registerApp:self.wxAppKey]; PayReq *request = [[PayReq alloc] init]; request.openID = self.wxAppKey; request.partnerId = parterId; request.prepayId = prePayId; request.package = package; request.nonceStr = nonceStr; request.timeStamp = [timestamp intValue]; request.sign = sign; if (![WXApi sendReq:request]) { [self paymentErrorWithMessage:@"抱歉,没法打开微信。请您安装最新版本微信"]; } } #pragma mark - 付款回调 - (void)paymentSuccess { if (self.delegate && [self.delegate respondsToSelector:@selector(paymentSuccess)]) { [self.delegate paymentSuccess]; } } - (void)paymentCancel { if (self.delegate && [self.delegate respondsToSelector:@selector(paymentCancel)]) { [self.delegate paymentCancel]; } } - (void)paymentErrorWithMessage:(NSString *)errorMessage { if (self.delegate && [self.delegate respondsToSelector:@selector(paymentResultWithError:)]) { [self.delegate paymentResultWithError:[NSError errorWithDomain:@"http://mobile.yx58.com/Api/Sdk/index" code:500 userInfo:@{NSLocalizedDescriptionKey:errorMessage}]]; } } // 支付宝客户端支付后回调 - (BOOL)handleOpenURL:(NSURL *)url { NSString *query = [[NSString getString:[url query]] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; if (![NSString isEmpty:query]) { AlixPayResult *result = [[AlixPayResult alloc] initWithResultString:query]; if (result.statusCode == 9000) { [self performSelector:@selector(paymentSuccess) withObject:self.tradeNo afterDelay:0.25f]; } else if (result.statusCode == 6001) { [self performSelector:@selector(paymentCancel) withObject:self.tradeNo afterDelay:0.25f]; } else { [self performSelector:@selector(paymentErrorWithMessage:) withObject:result.statusMessage afterDelay:0.25f]; } } return NO; } // 银联控件回调 - (void)UPPayPluginResult:(NSString *)result { if ([result isEqualToString:@"success"]) { [self performSelector:@selector(paymentSuccess) withObject:self.tradeNo afterDelay:0.25f]; } else if ([result isEqualToString:@"cancel"]) { [self performSelector:@selector(paymentCancel) withObject:self.tradeNo afterDelay:0.25f]; } else { [self performSelector:@selector(paymentErrorWithMessage:) withObject:result afterDelay:0.5f]; } } - (void)onResp:(BaseResp *)resp { // 微信支付返回处理 if ([resp isKindOfClass:[PayResp class]]) { PayResp *response = (PayResp *)resp; NSLog(@"Pay Responder Code = %zd", response.errCode); [self wxpayResultCode:response.errCode]; } } // 微信支付客户端回调 - (void)wxpayResultCode:(int)resultCode { NSString *errMsg = nil; if (resultCode == 0) { [self performSelector:@selector(paymentSuccess) withObject:self.tradeNo afterDelay:0.25f]; return; } else if (resultCode == -1) { errMsg = @"未知错误"; } else if (resultCode == -2) { errMsg = @"取消微信支付"; } else if (resultCode == -3) { errMsg = @"发送失败"; } else if (resultCode == -4) { errMsg = @"受权失败"; } else if (resultCode == -5) { errMsg = @"微信不支持"; } if (resultCode == -2) { [self performSelector:@selector(paymentCancel) withObject:self.tradeNo afterDelay:0.25f]; } else { [self performSelector:@selector(paymentErrorWithMessage:) withObject:@"微信支付失败" afterDelay:0.25f]; } } @end
1.在调用后台接口,生成订单成功后调用一下代码:
[[WanPaymentData instance] setDelegate:self]; [WanPaymentData instance].paymentType = paymentType; [[WanPaymentData instance] requestPaymentURLWithResult:dict];
2.遵照协议并实现代理方法:
#pragma mark --<WanPaymentDataDelegate> - (void)paymentSuccess{ [self removeFromSuperview]; if (self.paySuccessBlock) { self.paySuccessBlock(); } } - (void)paymentCancel{ [PPUIUtils showStateInWindow:@"您已放弃付款"]; } - (void)paymentResultWithError:(NSError *)error{ NSString *msg = [error localizedDescription]; [PPUIUtils showStateInWindow:msg]; }
3.在AppDelegate添加如下代码
-(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{
if ([url.host isEqualToString:@"safepay"]) {
return [[WanPaymentData instance] handleOpenURL:[NSURL URLWithString:url.absoluteString]];
}
return [WXApi handleOpenURL:url delegate:[WanPaymentData instance]];
}
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(nonnull id)annotation{
if ([url.host isEqualToString:@"safepay"]) {
return [[WanPaymentData instance] handleOpenURL:[NSURL URLWithString:url.absoluteString]];
}
return [WXApi handleOpenURL:url delegate:[WanPaymentData instance]];
}
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options{
if ([url.host isEqualToString:@"safepay"]) {
return [[WanPaymentData instance] handleOpenURL:[NSURL URLWithString:url.absoluteString]];
}
return [WXApi handleOpenURL:url delegate:[WanPaymentData instance]];
}