分享

DELPHI移动端支付宝支付

 A芝兰之室 2017-10-13

Delphi XE7 Android

应用接入支付宝SDK的方法

 

 

1      应用场景和准备工作:

  1. 采用XE系列开发的android apps。
  2. apps中需要集成支付宝的支付能力。
  3. 支付到指定的商家(一般就是软件开发商自己啦),商家需要事先在支付宝的开放平台申请开通【支付宝无线快捷支付】,具体请百度。
  4. 开通【无线快捷支付】后,支付宝应该返回给商家如下几个重要参数:

PARTNER(商户ID): 一个16为的字符串,应该都是数字。

SELLER(商户名):多数是商户的邮件地址。

RSA_PRIVATE(商户私钥 ): 一个848位的字符串,采用pkcs8编码过。

RSA_PRIVATE(商户私钥 ): 一个848位的字符串。

RSA_PUBLIC(商户公钥):一个218位的经过pkcs8编码的字符串。这个公钥并没有用到,是支付宝后台用的。

  1. 5.         以上几个参数,都是支付宝再审核通过后,通过邮件发送给商家的,其中RSA的两个公私钥,需要商户自己根据手册自行生成并上传和保存,具体这一步请务必参考支付宝开放平台的说明。

 

2      XE7中的开发准备工作:

  1. 下载一个java2op.exe,备用。
  2. 建立一个android的应用。
  3. copy支付宝sdk的三个jar包到工程目录(最好和你的pas文件一个目录,最好也把java2op这个文件copy到这里。
  4. 在IDE右边的ProjectManager中,添加支付宝SDK(android)的三个jar包,如右图。细心的朋友可能发现多了一个jar包:signutils.jar,这个不是支付宝(alipay)sdk带的,是我自己加上的,用途我们稍后再说。
  5. 打开一个CMD命令行窗口。
  6. 从命令行里,CD到你的工程目录,有jar包的地方,执行如下命令:

                         i.              java2op -jar alipaysdk.jar -unit alipaysdk

                       ii.              java2op -jar alipaysecsdk.jar -unit alipaysecsdk

                     iii.              javs2op -jar alipayutdid.jar -unit alipayutdid

  1. 如果一切顺利,在当前目录应该发现新增的这三个pas文件。如图:

 

 

 

 

3      XE7中的代码工作:

  1. 请按照支付宝SDK的要求,在androidmanifest.template.xml文件总,增加sdk中的activity的引用,如图:
  2. 具体这个xml在什么位置,以及这个activity的字符串从何处得来,我就不费力解释了,相信大家都知道。
  3. 在支付宝SDK的接入手册中,针对混淆部分的要求,可以忽略,不用关心。
  4. 在适当的pas文件中,增加对之前生成的三个pas的引用(附带几个要用到的单元,也一并加上吧),如图:
  5. 注意:在编译的时候,这三个pas文件,会报错,几乎都是某个"property a"重复定义的问题,请直接手动把每个报错的‘a’都改为‘aaaaa’,随便什么即可,删除也行。
  6. 开始加入最关键的代码,例如我们要在一个按钮下开始支付,支付的商品名称、描述和价格,我们可以用三个edit来作为测试输入,这里就不截图描述了,过程如下:

                     iv.             

 
   


在pas某个位置,声明三个常量或者属性备用,这三个属性就是之前支付宝返回的参数。

                       v.              在所谓的【支付按钮】的事件里,写如下代码:

procedure TForm3.Button1Click(Sender: TObject);

var

  PayTask: JPayTask;

  PayClass: JPayTaskClass;

  JOrderInfo: JString;

  OrderInfo,Sign: String;

begin

  PayClass := TJPayTask.JavaClass;

  PayTask := PayClass.init(MainActivity);

  OrderInfo := Self.getOrderInfo('abcd','body','0.01');

  sign := Self.Sign(OrderInfo);

  OrderInfo := OrderInfo + '&sign="'+sign+'"';

  OrderInfo := OrderInfo + '&sign_type="RSA"';

  Self.Memo1.Lines.Text := OrderInfo;  //调试用,你懂的。

  JOrderInfo := StringToJString(OrderInfo);

  PayTask.pay(JOrderInfo);

end;

                     vi.              getOrderInfo: 这个函数文档后面会有,是按照支付宝的要求,对订单信息进行格式化处理的,这个函数中调用了一个getTradeNo,是自定义的,也就是生成订单号的,保证不重复即可,随便写。

                   vii.              Sign函数:这个函数就用到了之前在前面看到的signutils.jar这个包,原本支付宝的sdk是没有这包的,这个包是我自己用java编写并加入到项目中的,原因就是:支付宝sdk要求,需要对订单信息进行rsa签名,这个签名过程比较复杂,熟悉java的,可以下载java的demo来看一下,我尝试用delphi下的一些工具和第三方组件,但都失败了,可能是我还不是很熟悉吧,我就把java中的函数封装到这个jar中,供delphi来调用,很好用,文档的后面也会有这个函数的代码,但具体今后每个开发者用什么方法来给订单做sign的签名,只能大家各自想办法了。文档中,我会链接这个jar给大家。

                 viii.              如果一切正常,应该可以看到支付宝的界面了,至于调试过程中出现的各种错误,只能百度。

                     ix.              系统繁忙,请稍后重试:ALI64: 这个错误几乎都是订单信息格式不对,或者支付宝返回的各种参数没有用对,还有可能是没有开通无线快捷支付。

                       x.              系统繁忙,请稍后重试:ALI10:这个错误主要是sign签名不对。

  1. 附录代码:

function TForm3.getOrderInfo(subject, body, price: string): string;

var

  s: string;

begin

              // 签约合作者身份ID

  s := 'partner="' + PARTNER + '"';

              // 签约卖家支付宝账号

  s := s + '&seller_id="' + SELLER + '"';

              // 商户网站唯一订单号

       s := s+ '&out_trade_no="' + getOutTradeNo + '"';

     // 商品名称

  s := s + '&subject="' + subject + '"';

              // 商品详情

  s := s + '&body="' + body + '"';

              // 商品金额

  s := s + '&total_fee="' + price + '"';

              // 服务器异步通知页面路径

  s := s + '&notify_url="' + 'http://你的业务后台地址,一定要写,要合法"';

              // 服务接口名称, 固定值

  s := s + '&service="mobile.securitypay.pay"';

              // 支付类型, 固定值

  s := s + '&payment_type="1"';

              // 参数编码, 固定值

  s := s + '&_input_charset="utf-8"';

              // 设置未付款交易的超时时间

              // 默认30分钟,一旦超时,该笔交易就会自动被关闭。

              // 取值范围:1m~15d。

              // m-分钟,h-小时,d-天,1c-当天(无论交易何时创建,都在0点关闭)。

              // 该参数数值不接受小数点,如1.5h,可转换为90m。

  s := s + '&it_b_pay="30m"';

 

              // extern_token为经过快登授权获取到的alipay_open_id,带上此参数用户将使用授权的账户进行支付

              // orderInfo += "&extern_token=" + "\"" + extern_token + "\"";

 

              // 支付宝处理完请求后,当前页面跳转到商户指定页面的路径,可空

  s := s + '&return_url="m.alipay.com"';

 

              // 调用银行卡支付,需配置此参数,参与签名, 固定值 (需要签约《无线银行卡快捷支付》才能使用)

              // orderInfo += "&paymethod=\"expressGateway\"";

  Result := s;

 

end;

function TForm3.getOutTradeNo: string;

var

  G: TGuid;

  S: string;

begin

  G := TGuid.NewGuid;

  S := G.ToString;

  S := S.Substring(0,15);

  Result := 'abcdefghijklmn';

end;

function TForm3.Sign(const Orders: string): string;

var

  SignClass: JSignUtilsClass;

  Js,jpri: JString;

begin

  Result := '';

  try

    Js := StringToJString(Orders);

    JPri := StringToJString(RSA_PRIVATE);

    SignClass := TJSignUtils.JavaClass;

    SignClass.init;

    js := SignClass.sign(js,jpri);

    //js := SignClass.DoURLEncode(js);

    Result := JStringToString(js);

  finally

  end;

 

 

其他:

4      真实业务场景的考虑

按照支付宝或者微信支付的开发手册的说法,一个标准的客户端接入支付业务模型应该是这样的,我忽略时序图,只用文字描述:

  1. 用户登录客户端,选择商品,然后点击客户端支付。
  2. 客户端收集商品信息,然后调用自己业务平台的预付款接口。
  3. 业务平台根据客户端提交的商品信息,生成自己的订单号等内容,并按照第三方支付的要求对订单信息进行拼装组合,并编码和签名。
  4. 业务平台返回签名后的订单信息给客户端。
  5. 客户端根据这个签名信息,呼出客户端的第三方支付系统,完成支付。

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多