支付寶,微信支付集成

首先要弄個支付相關的類

@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];
    
}


當然了,這裏不管是支付寶還是微信支付,成功也只是客戶端返回的成功,最保險的還是客戶端請求自己的服務器,在自己的服務器上確認支付真的已經成功了,再繼續業務流程,畢竟支付流程還是要謹慎一點的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章