All Articles

Swift iOS App唤起支付宝支付的简单教程

1. 前言

作为一名后端程序员,整个API链的调用联调是否能摒除所有的外部依赖是非常重要的,测试的流程贯通关系到整个开发的顺畅程度。支付系统的联调麻烦就麻烦在有外部系统的依赖。虽然在做开发的时候可以在单元测试代码中进行Mock来绕过外部的依赖,但真实的e2e测试还是必须的,这个时候就需要引入外部支付系统的接口了。

目前国内的支付系统主要就是支付宝和维信支付。微信支付有点忘记了,但支付宝的app支付和网页支付是分开的2个独立的功能,也就是说公司的app可能只签了app支付而没有签网页支付。这种情况下在测试的时候,后端下单之后就无法使用自己生成的二维码然后用手机扫码支付测试了,必须是直接在手机的app内进行测试。这就很麻烦。所以本文会做一个教程,简单教下如何创建一个简单的app,可以使用后端下单生成的返回字串来唤醒支付宝进行支付,以打通整个支付流程。

2. 创建iOS项目

首先需要注册一个Apple开发者账号,因为没有任何账号的话,是无法对App进行打包和部署到手机上进行测试的。注册去:https://developer.apple.com/,点右上角的Account,按引导注册即可。然后打开xocde,点开Perferences -> Accounts,点左下角的+添加自己的账号。

然后打开xcode,创建新项目。

题外:如果想认真学习下Swift的话,官方Tutorials教程在:SwiftUI Tutorials。此外,还有The swift programming language

3. 安装cocospods

cocospods是iOS项目的依赖管理工具,类似nodejs的npm,基本上做项目都需要。最方便的的一点是这东西在安装的时候,会把一些对应的配置文件都更新好,对于我这样的新手来说就少了很多事情。

几篇参考:

# 安装cocospods本体
$ brew update --verbose
$ brew install cocospods --verbose
# 安装数据库,这个repo超级大,一共有将近1个GB的数据,建议用代理加速
$ git clone https://github.com/CocoaPods/Specs.git ~/.cocoapods/repos/trunk
# 完成后测试下效果,是否可以搜到dep,有结果返回就OK了
$ pod search Alamofire

4. 安装Alipay SDK

到刚才创建的新项目的根目录下,首先需要创建pod的配置文件,类似package.json

$ pod init

会生成一个Podfile,然后编辑该文件,添加Alipay SDK,添加在# Pods for AlipayTest这行下:pod 'AlipaySDK-iOS'

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'AlipayTest' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for AlipayTest
  pod 'AlipaySDK-iOS'

  target 'AlipayTestTests' do
    inherit! :search_paths
    # Pods for testing
  end

  target 'AlipayTestUITests' do
    # Pods for testing
  end

end

最后在repo的根目录下执行安装命令

$ pod install

安装完成的dep都放在:Pods/下,Alipay SDK在:/Pods/AlipaySDK-iOS

后续需要关闭xcode,使用新生成的AlipayTest.xcworkspace文件来打开项目。

更多细节可以看支付宝官方的:客户端 iOS 集成流程

5. 桥接Alipay SDK的Header文件

因为Alipay SDK是使用ObjC写的,所以在Swift项目中使用需要做一步工作:引入桥接的Header文件。

执行创建文件操作,选择ObjC文件,名字随意,实际上这个ObjC文件我们后续可以直接删除,没用。IDE会问是否需要创建桥接Header,点击蓝色按钮选是,这才是我们创建ObjC文件的真正目的。

操作完成后,删除ObjC文件,打开桥接Header文件,并添加:# import <AlipaySDK/AlipaySDK.h>

6. 实现唤起Alipay

打开创建新项目时默认生成的:ContentView。页面上添加一个 TextEditor 用来输入后端下单之后生成的sign字符串,然后一个 Button 来执行确认唤起。

要正确唤起支付宝,并能够正确支付,需要注意几个点:

  • 进行测试的手机上需要安装好真正的业务app(我们做的支付测试app是为了测通支付流程用的,不是真正的应用app,这里说需要安装好的是我们实际接入支付的真正的业务app)
  • 用来输入sign字符串的 TextEditor,在输入的时候需要删除之前的PlaceholderInput the sign here,我是没找到这个控件应该怎么加Placeholder…
  • 代码中AlipaySDK.defaultService().payOrderfromScheme需要替换成第二点中提到的真正业务app的项目名字,也就是支付宝支付完成后的回调app
    • 这里不知道为什么,填写我们的测试app的名字支付宝支付会报错,具体应该和iOS应用配置打包细节有关,这个我不是专业的就不琢磨了,直接用真正的业务app的名字即可
    • 所以这个支付的回调是不会走回我们的这个支付测试app的,而是会回到业务app,切记,不过无所谓,毕竟我们只是要完成支付打通支付流程而已
//
//  ContentView.swift
//  honors
//
//  Created by Jonathan Dai on 2022/4/14.
//

import SwiftUI

struct ContentView: View {
    @State var editor: String = "Input the sign here"
    @State var console: String = "Console:\n"
    
    var body: some View {
        VStack {
            SwiftUI.Group {
                Text("Pay with order sign").padding().frame(width: nil).border(Color.black, width: 2)
                TextEditor(text: $editor)
                    .padding()
                    .border(Color.black, width: 1)
                Button(action: {
                    print("Button 'Go to Alipay' clicked")
                    gotoAlipay()
                }) {
                    Text("Go to Alipay")
                }
                .padding(.all)
                TextEditor(text: $console)
                    .padding()
                    .border(Color.black, width: 1)
            }
        }
    }
    
    func gotoAlipay() {
        self.console += "gotoAlipay\n"
        print("gotoAlipay: sign: " + self.editor)
        AlipaySDK.defaultService().payOrder(self.editor, fromScheme: "YourBusinessAppNameHere", callback: { (resultDic) -> Void in
            print("Alipay reslut = \(String(describing: resultDic))");
            let resultDic = resultDic! as Dictionary
            if let resultStatus = resultDic["resultStatus"] as? String {
                if resultStatus == "9000" {
                    self.console += "支付成功\n"
                } else {
                    self.console += "支付失败\n"
                }
            }
        })
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            ContentView()
        }
    }
}

UI长这样

操作:

  • 后端下单,生成app唤起用的sign字符串
  • 拷贝到该测试应用的第一个 TextEditor 里
  • 点击按钮Go to Alipay
  • 即可

EOF

Published 2022/4/15

Some tech & personal blog posts