支付宝流程
模拟订单模拟支付行为
下图中:支付类型----移动端只负责 "1.支付" 就行,其余后台管
其中处理订单号代码如下
通过各种算法生成随机订单号
二级商户
微信支付流程
#import "AppDelegate.h"
#import "WXApi.h"
@interface AppDelegate ()<WXApiDelegate>
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//开启AFN框架内网路指示器(小菊花)
[AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
//定义顶部20高的状态栏属性
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];
//设置图片缓存策略
[SDImageCache sharedImageCache].maxCacheAge = 1024*1024*10;
//向微信注册
[WXApi registerApp:@"wx1a851bd5c91204b3"];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
LoginController *loginController = [[LoginController alloc] init];
ZYNavigationController *nav = [[ZYNavigationController alloc] initWithRootViewController:loginController];
self.window.rootViewController = nav;
[self.window makeKeyAndVisible];
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
{
[[NSNotificationCenter defaultCenter] postNotificationName:@"PAY_FINISH_NOTIF" object:nil]
//如果支付成功则去后台查询支付结果再展示用户实际支付结果。注意 一定不能以客户端返回作为用户支付的结果,应以服务器端的接收的支付通知或查询API返回的结果为准。
NSString *strMsg = [NSString stringWithFormat:@"支付结果"];
switch (resp.errCode) {
case WXSuccess:
strMsg = @"支付结果:成功!";
NSLog(@"支付成功-PaySuccess,retcode = %d", resp.errCode);
//从服务器端再次确认支付是否成功
[self makeSureChargeStatus];
break;
default:
strMsg = [NSString stringWithFormat:@"支付结果:失败!retcode = %d, retstr = %@", resp.errCode,resp.errStr];
NSLog(@"错误,retcode = %d, retstr = %@", resp.errCode,resp.errStr);
break;
}
}
//从服务器端再次确认支付是否成功
- (void)makeSureChargeStatus
{
/*
### 查询充值结果
* 地址
http://dyt-win/greapost/rest/charge/status
* 参数
{"userId":"a0d8ec16f42b11e6b50ed279e40c8da1","chargeId":"a0d8ec16f42b11e6b50ed279e40c8da1"}
* 返回值
{"success":true,"state":"SUCCESS"}
ps: state 可选值
PAYSTATE_PREFAIL = "PREFAIL";
PAYSTATE_NOTPAY = "NOTPAY";
PAYSTATE_REFUND = "REFUND";
PAYSTATE_SUCCESS = "SUCCESS";
PAYSTATE_CLOSED = "CLOSED";
PAYSTATE_USERPAYING = "REVOKED";
PAYSTATE_PAYERROR = "REVOKED";
PREFAIL-统一下单失败
SUCCESS—支付成功
REFUND—转入退款
NOTPAY—未支付
CLOSED—已关闭
REVOKED—已撤销(刷卡支付)
USERPAYING--用户支付中
PAYERROR--支付失败(其他原因,如银行返回失败)
*/
NSDictionary *parameters = @{
@"userId": [Tool sharedTool].userID,
@"chargeId": [Tool sharedTool].chargeId
};
[HttpRequest postWithURLString:@"greapost/rest/charge/status" parameters:parameters success:^(id responseObject) {
NSLog(@"支付结果查询:%@",responseObject);
if (responseObject[@"success"]) {
[self showPayState:responseObject[@"state"]];
} else {
[Tool showErrorSVProgressHUDWithStatus:responseObject[@"msg"]];
}
} failure:^(NSError *error) {
[Tool showErrorSVProgressHUDWithStatus:ServerNetworkError];
}];
}
//获取支付状态
- (void)showPayState:(NSString *)state
{
if ([state isEqualToString:@"NOTPAY"]) {
[Tool showWarningSVProgressHUDWithStatus:@"未支付" time:2.0];
return;
}
if ([state isEqualToString:@"SUCCESS"]) {
[Tool showSuccessSVProgressHUDWithStatus:@"支付成功"];
return;
}
if ([state isEqualToString:@"REFUND"]) {
[Tool showWarningSVProgressHUDWithStatus:@"转入退款" time:2.0];
return;
}
if ([state isEqualToString:@"REVOKED"]) {
[Tool showWarningSVProgressHUDWithStatus:@"已撤销" time:2.0];
return;
}
if ([state isEqualToString:@"CLOSED"]) {
[Tool showWarningSVProgressHUDWithStatus:@"已关闭" time:2.0];
return;
}
if ([state isEqualToString:@"PREFAIL"]) {
[Tool showWarningSVProgressHUDWithStatus:@"统一下单失败" time:2.0];
return;
}
if ([state isEqualToString:@"USERPAYING"]) {
[Tool showWarningSVProgressHUDWithStatus:@"用户支付中" time:2.0];
return;
}
if ([state isEqualToString:@"PAYERROR"]) {
[Tool showWarningSVProgressHUDWithStatus:@"支付失败(其他原因,如银行返回失败)" time:2.0];
return;
}
}
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
[[SDImageCache sharedImageCache] clearMemory];
[[SDWebImageManager sharedManager] cancelAll];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
@end
#import "ChargeController.h"
#import "WXApi.h"
@interface ChargeController ()<ChoosePayViewDelegate>
@property (nonatomic, weak) ChoosePayView *choosePayView;
@end
@implementation ChargeController
- (void)viewDidLoad {
[super viewDidLoad];
[self addSubViews];
}
- (void)addSubViews
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(popViewController) name:@"PAY_FINISH_NOTIF" object:nil];
self.title = @"充值";
}
- (void)popViewController
{
[self.navigationController popViewControllerAnimated:YES];
}
- (void)choosePayView
{
if(!_choosePayView){
_choosePayView = [[ChoosePayView alloc] initWithFrame:CGRectMake(0, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT)];
choosePayView.delegate = self;
choosePayView.money = money;//用户选中的充值面额
}
return _choosePayView;
}
//点击充值按钮,动画弹出微信.支付宝方式选中框
- (void)clickChargeButton:(UIButton *)ban
{
//懒加载添加,保证只添加一次
UIApplication *ap = [UIApplication sharedApplication];
[ap.keyWindow addSubview:self.choosePayView];
[UIView animateWithDuration:0.3 animations:^{
self.choosePayView.top = 0;
} completion:^(BOOL finished) {
count = 0;
}];
}
#pragma mark - choosePayViewDelegate
//选择支付方式代理方法
- (void)chooseAlipayOrWeChatPay:(PayType)payType
{
/*
### 充值
* 地址
http://dyt-win/greapost/rest/charge/unifiedorder
* 参数
{"userId":"a0d8ec16f42b11e6b50ed279e40c8da1","totalFee":"0.01"}
* 返回值
{"success":true,"package":"Sign=WXPay","appid":"wx1a851bd5c91204b3","sign":"773CC5445E6C38CF9D8B7BEDE2D5DC33","prepayid":"wx20170217141956a16afe8fb70522432780","partnerid":"1243435702","noncestr":"77qous9c45mceab6kuw86705igouz0m7","timestamp":"1487312412"}
*/
[self.choosePayView removeFromSuperview];
if (payType == kALiPayTYPE) {
NSLog(@"选中了支付宝支付方式");
[Tool showWarningSVProgressHUDWithStatus:@"暂时不支持支付宝支付" time:2.0];
} else {
NSLog(@"选中了微信支付方式");
//调起支付: 商户服务器生成支付订单,先调用【统一下单API】生成预付单,获取到prepay_id后将参数再次签名传输给APP发起支付。以下是调起微信支付的关键代码:
NSDictionary *parameters = @{
//传入用户id
@"userId": [Tool sharedTool].userID,
//传入选中充值面额
@"totalFee": self.choosePayView.money
};
[HttpRequest postWithURLString:@"greapost/rest/charge/unifiedorder" parameters:parameters success:^(id responseObject) {
/*
支付结果: {
appid = wx1a851bd5c91204b3;
noncestr = 8bv12duoidtoqo0pqpdz1z41wy9dxdse;
package = "Sign=WXPay";
partnerid = 1243435702;
prepayid = wx201702171457555d8a431e470433379896;
sign = B2DB5E26D59B19134EF3660AC6C2711F;
success = 1;
timestamp = 1487314687;
chargeId = 3d626bc3f5e211e6bc070050563731d8;
}
*/
NSLog(@"支付结果: %@",responseObject);
if ([responseObject[@"success"] boolValue]) {
[[Tool sharedTool] setChargeId:responseObject[@"chargeId"]];
//服务器返回订单成功后, 进行微信支付
PayReq *request = [[PayReq alloc] init];
request.partnerId = responseObject[@"partnerid"];
request.prepayId= responseObject[@"prepayid"];
request.package = @"Sign=WXPay";
request.nonceStr= responseObject[@"noncestr"];
request.timeStamp= [responseObject[@"timestamp"] intValue];
request.sign= responseObject[@"sign"];
if ([WXApi isWXAppInstalled]) {
[WXApi sendReq:request];
} else {
[Tool showWarningSVProgressHUDWithStatus:@"未安装微信应用" time:2.0];
}
} else {
[Tool showErrorSVProgressHUDWithStatus:[NSString stringWithFormat: @"%@",responseObject[@"msg"]]];
}
} failure:^(NSError *error) {
NSLog(@"服务器请求订单失败 error:%@",error.localizedDescription);
// [Tool showErrorSVProgressHUDWithStatus:ServerNetworkError];
}];
}
}
- (void)dismissChoosePayView
{
[self.choosePayView removeFromSuperview];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
@end