美文网首页
iOS 拉去支付宝报销管家发票,支付宝推模式报销

iOS 拉去支付宝报销管家发票,支付宝推模式报销

作者: 你duck不必呀 | 来源:发表于2020-12-17 11:04 被阅读0次
    配图.jpg

    获取支付宝的发票,支付宝开放平台的文档很详细文档,这里总结一下过程

    1. 需要支付宝开放平台账号 入口

    2. 在开放平台注册你的app


      image.png

    按照官方文档上的流程去做,很详细
    注意1,提交完app信息需要在能力列表选择报销助手

    image.png

    注意2,支付宝要求必须设置接口加签方式,不然不能提交审核


    image.png

    加签方式 文档说明

    这里选择的模式是公钥方式,加签方式SHA256withRSA

    你自己生成一对密钥,把公钥发给支付宝,支付宝也会生成一对密钥,提交后支付宝会把公钥发给你

    提交审核,通过后appID就可以用了

    1. 应用的appID需要和商家账号PID绑定。
      调用授权类接口,需要绑定PID 相关文档

    2. 推模式报销需要申请isvAppCode,这个只能找支付宝客服,或者发邮件

    image.png

    报销模式文档

    推模式报销:可以获取到支付宝报销管家里的所有发票
    拉模式报销:只能获取商家抬头的发票

    这里以推模式报销为例: IMG_1760.jpg

    以上步骤都完成,准备工作就完了

    1. 获取报销授权令牌

    建议让后台去做,接入支付宝SDK自动签名 过程很省事。这里演示iOS手动签名获取令牌的过程,比较麻烦~
    获取支付宝令牌文档
    生成密钥请求签名

    (1). 生成待签名字符串

    添加文档上必传的参数,按照ASCII排序生成字符串

    ///返回待加密字符串
    -(NSString *)signatureStringWith:(NSDictionary*)parameters{
        
        NSMutableString *contentString = [NSMutableString string];
        NSArray *allKeys = [parameters allKeys];
        
        NSArray *sortedKeyArray = [allKeys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
            return [obj1 compare:obj2 options:NSNumericSearch];
        }];
        
        for (NSString *key in sortedKeyArray) {
            [contentString appendFormat:@"%@=%@&",key,[parameters valueForKey:key]];
        }
       
        NSString *signatureStr = [NSString stringWithString:[contentString substringWithRange:NSMakeRange(0, [contentString length] - 1)]];
        return signatureStr;
    }
    

    (2). 加密字符串,签名

    sha256加密,需要导入头文件:
    #import <CommonCrypto/CommonDigest.h>

    //SHA2加密
    - (NSData *) sha256:(NSString *)str {
        const char *s = [str cStringUsingEncoding:NSUTF8StringEncoding];
        NSData *strData = [NSData dataWithBytes:s length:strlen(s)];
        uint8_t digest [CC_SHA256_DIGEST_LENGTH] = {0};
        CC_SHA256(strData.bytes, (CC_LONG)strData.length, digest);
        NSData *data = [NSData dataWithBytes:digest length:CC_SHA256_DIGEST_LENGTH];
        return data;
    }
    

    RSA2 加密,什么是RAS2可以自行百度,这里Objective-C-RSA实现了RSA2的签名,验签

    (3)用生成的密钥中的私钥对加密结果进行签名

    密钥一般是从后台获得,这里需要把获得的密钥字符串转换成SecKeyRef密钥类型:

    这里Objective-C-RSA开源库实现了字符串转SecKeyRef密钥类型,以及RSA2加密,解密,签名,验签的过程

    /// 加密,密钥签名
    - (NSString *) sign:(NSString *)storString{
       // 使用哈希算法获取字符串摘要
       // sha256加密
       NSData *outData = [self sha256:storString];
       SecKeyRef pKey = [RSA addPrivateKey:[self getPrivateKey]];
       
       size_t siglen = SecKeyGetBlockSize(pKey);
       uint8_t* signedHashBytes = malloc(siglen);
       memset(signedHashBytes, 0x0, siglen);
       SecKeyRawSign(pKey,
                     kSecPaddingPKCS1SHA256,
                     outData.bytes,
                     outData.length,
                     signedHashBytes,
                     &siglen);
       NSData* signedHash = [NSData dataWithBytes:signedHashBytes length:(NSUInteger)siglen];
       NSString *signString = [signedHash base64EncodedStringWithOptions:NSUTF8StringEncoding];
       NSLog(@"=1===== %@",signString);
       if (!signString) {
           return @"";
       }
       return signString;
    }
    

    RSA 是开源库中的工具类,实现了密钥字符串转换成SecKeyRef密钥类型

    这样就完成了签名过程

    (4) 调用支付宝接口,获取令牌

    网络请求用到AFNetworking

    -(void)getAliPayToken {
        
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
        NSString *timeStr = [dateFormatter stringFromDate:NSDate.date];
        
        //参数字典
        NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
        [parameters setObject:timeStr forKey:@"timestamp"];
        [parameters setObject:@"alipay.ebpp.invoice.isvtoken.reim.apply" forKey:@"method"];
        [parameters setObject:APPID forKey:@"app_id"];
        [parameters setObject:@"RSA2" forKey:@"sign_type"];
        [parameters setObject:@"1.0" forKey:@"version"];
        [parameters setObject:@"utf-8" forKey:@"charset"];
        [parameters setObject:@"{\"isv_app_code\":\"ekuaibao_tinyapp\"}" forKey:@"biz_content"];
        [parameters setObject:[self signatureStringWith:parameters] forKey:@"sign"];
        //生成签名字符串
        NSString *signatureStr = [self signatureStringWith:parameters];
        
        AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
        manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/plain", @"text/javascript", @"text/json", @"text/html", nil];
        NSString *postUrl = @"https://openapi.alipay.com/gateway.do?";
    
        [manager POST:postUrl parameters:parameters headers:nil progress:^(NSProgress * _Nonnull uploadProgress) {
            
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            //do ......
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        }];
        
    }
    
    1. 跳转到支付宝,获取发票信息

    跳转方式和其他的app一样,按照支付宝文档说明替换相应参数就可以
    获取到发票信息,支付宝会通过UniversalLink回掉你的app,并且携带发票信息

    alipays://platformapi/startapp?appId=2021001125620243&ap_framework_sceneId=1300&thirdPartSchema=#testapp://#&page=pages/package-detail/index?isv_app_code%3D#appCode#%26isv_token%3D#token#%26isv_serial_no%3D#serialNo#%26isv_register_no%3D#registerNo#%26options%3D#options#

    - (void)popToAliPayApp{
    
        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:self.urlStr]];
            // NOTE: ------  对alipays:相关的scheme处理 -------
            // NOTE: 若遇到支付宝相关scheme,则跳转到本地支付宝App
            NSString* reqUrl = request.URL.absoluteString;
            if ([reqUrl hasPrefix:@"alipays://"] || [reqUrl hasPrefix:@"alipay://"]) {
                // NOTE: 跳转支付宝App
                BOOL bSucc = [[UIApplication sharedApplication] openURL:request.URL];
         
                // NOTE: 如果跳转失败,则跳转itune下载支付宝App
                if (!bSucc) {
                    
                    NSLog(@"跳转失败");
                    
                }
            }
    }
    
    1. 支付宝回掉,系统会调用continueUserActivity
    - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler{
    
      //这里就能看到从支付宝获取到的发票信息了
      NSLog(@"%@",userActivity.webpageURL.absoluteString);
      return YES;
    }
    
    1. 发票信息解密

    调用支付宝API解密

    以上就是获取支付宝发票流程,支付宝文档说的很详细,在此记录一下;强烈建议后台通过支付宝SDK获取令牌以及后续的解密过程会舒适很多

    相关文章

      网友评论

          本文标题:iOS 拉去支付宝报销管家发票,支付宝推模式报销

          本文链接:https://www.haomeiwen.com/subject/ikcngktx.html