首先要弄个支付相关的类
@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];
}
当然了,这里不管是支付宝还是微信支付,成功也只是客户端返回的成功,最保险的还是客户端请求自己的服务器,在自己的服务器上确认支付真的已经成功了,再继续业务流程,毕竟支付流程还是要谨慎一点的。
转载于:https://blog.51cto.com/liyun2422/1732987