文档章节

iOS集成支付宝支付--Swift

上官尘
 上官尘
发布于 2016/02/26 16:42
字数 1122
阅读 1521
收藏 5
点赞 1
评论 0

       如果要了解整个支付流程可以阅读文章《手机App集成微信支付&支付宝-iOS&Android完整版》。
如果不想看本文的话可以直接到Github下载Demo源码。下载源码后只需要修改MyConstants.swift文件中的支付宝相关账号即可运行。

申请PID

到支付宝商家服务网页申请快捷支付。

SDK

首先从支付宝开放平台下载SDK. 解压后的目录下包含「服务端demo」和「客户端demo」。「客户端demo」包含了集成支付宝所需要的所有文件。

RSA加密

整个支付流程我在文章《手机App集成微信支付&支付宝-iOS&Android完整版》中有详细描述。
为了保证安全,防止支付结果被截获,在生成订单和处理支付结果的时候就需要做安全校验。生成订单时对数据签名,收到支付结果时对数据进行签名验证,以检验数据是否被篡改过。支付宝目前采用RSA加密方式做签名验证。

RSA加密算法除了可加解密外,还可用来作签名校验。
简单的说,RSA会生成一个私钥和一个公钥,私钥你应该独自保管,公钥你可以分发出去。
做签名验证时,你可以用私钥对需要传输的数据做签名加密,生成一个签名值,之后分发数据,接收方通过公钥对签名值做校验,如果一致则认为数据无篡改。

生成公钥和私钥

用openssl生成商户的公钥和私钥,私钥用于提交支付申请时加密,而公钥要在商家服务页面上提交,换取到支付宝的公钥。
对于iOS来说,私钥要转为PKCS8格式,即下述代码的第三行!

openssl genrsa -out rsa_private_key.pem 1024 
openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem 
openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt

链接库

首先吧 AlipaySDK.framework 和 AlipaySDK.bundle 拖到你的项目里面。然后把demo目录下面的openssl和Util两个目录拖到你的工程下面。然后在 Build Settings => Header Search Paths => 添加 "$(SRCROOT)/openssl" 和 "$(SRCROOT)/Util"
否则会有类似报错:"openssl/asn1.h file not found"。

在Build Phases选项卡的Link Binary With Libraries中,增加以下依赖:
alipay依赖
其中,需要注意的是:
如果是Xcode 7.0之后的版本,需要添加libc++.tbd、libz.tbd;
如果是Xcode 7.0之前的版本,需要添加libc++.dylib、libz.dylib

新建一个Bridging-Header.h文件,并把该文件的路径添加到 Build Settings => Objective-C Bridging Header。然后在该文件中添加下面两行:

#import <AlipaySDK/AlipaySDK.h> #import "RSADataSigner.h"

如果你的服务器不支持Https,请在info.plist文件里面添加如下代码:

 <key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict>

由于支付包支付成功后需要返回App,那么你就需要设置你App独有的Schema:选择你的项目,选择Info,在URL Types中添加一个schema,并设置Url Schemas.

Coding

到这一步,整个配置过程就已经完成了。下面的工作就是Coding部分了。

 
        let aliOrder = AlipayOrder(partner: AlipayPartner, seller: AlipaySeller, tradeNO: order.id, productName: order.title, productDescription: order.content, amount: order.price, notifyURL: AlipayNotifyURL, service: "mobile.securitypay.pay", paymentType: "1", inputCharset: "utf-8", itBPay: "30m", showUrl: "m.alipay.com", rsaDate: nil, appID: nil)
        
        
        let orderSpec = aliOrder.description //orderA.description
        
        let signer = RSADataSigner(privateKey: AlipayPrivateKey)
        let signedString = signer.signString(orderSpec)
        
        let orderString = "\(orderSpec)&sign=\"\(signedString)\"&sign_type=\"RSA\""
        
        print(orderString)
        
        AlipaySDK.defaultService().payOrder(orderString, fromScheme: AppScheme, callback: {[weak self] resultDic in
            if let strongSelf = self {
                print("Alipay result = \(resultDic as Dictionary)")
                let resultDic = resultDic as Dictionary
                if let resultStatus = resultDic["resultStatus"] as? String {
                    if resultStatus == "9000" {
                        strongSelf.delegate?.paymentSuccess(paymentType: .Alipay)
                        let msg = "支付成功!"
                        let alert = UIAlertView(title: nil, message: msg, delegate: nil, cancelButtonTitle: "好的")
                        alert.show()
                        //strongSelf.navigationController?.popViewControllerAnimated(true)
                    } else {
                        strongSelf.delegate?.paymentFail(paymentType: .Alipay)
                        let alert = UIAlertView(title: nil, message: "支付失败,请您重新支付!", delegate: nil, cancelButtonTitle: "好的")
                        alert.show()
                    }
                }
            }
            })

AlipayOrder的description属性如下:

    var description:String {
        var desc = ""
        desc += "partner=\"\(partner)\""
        desc += "&seller_id=\"\(seller)\""
        desc += "&out_trade_no=\"\(tradeNO)\""
        desc += "&subject=\"\(productName)\""
        desc += "&body=\"\(productDescription)\""
        desc += "&total_fee=\"" + amount.format("0.2") + "\""
        desc += "&notify_url=\"\(notifyURL)\""
        desc += "&service=\"\(service)\""
        desc += "&payment_type=\"\(paymentType)\""
        desc += "&_input_charset=\"\(inputCharset)\""
        desc += "&it_b_pay=\"\(itBPay)\""
        desc += "&show_url=\"\(showUrl)\""
        
        if let rsaDate = rsaDate {
            desc += "&sign_date=\(rsaDate)"
        }
        
        if let appID = appID {
            desc += "&app_id=\(appID)"
        }
        
        return desc
    }

通知服务器支付成功

如果支付成功后,支付宝服务器会向你的服务器 notify URL 发起支付成功的请求。这样就可以在服务端实现一些相关的业务逻辑,比如标记订单为已支付,发短信给用户等。notify URL的具体实现请查看文章《iOS&Android集成支付宝-server篇(PHP)》

查看完整代码请移步Github

如需转载请保留原文链接


本文转载自:http://www.qinyejun.com/ios/ios-alipay-swift/

共有 人打赏支持
上官尘
粉丝 6
博文 38
码字总数 9881
作品 0
普陀
程序员
全屏手势返回插件 - BBGestureBack

BBGestureBack Full screen return gesture(全屏手势返回 滑动返回 pop 动画效果) iOS 侧滑返回 BBGestureBack iOS 全屏手势返回 滑动返回 pop 动画效果 现在市场上的主流app都有用到各种侧...

Bonway ⋅ 05/30 ⋅ 0

iOS高仿微信、仪表盘、图片标注图片滤镜、高斯模糊、上拉加载、下拉刷新等源码

iOS精选源码 Swift-图片画框标注(http://www.code4app.com/thread-29884-1-1.html) Swift版的上拉加载, 下拉刷新控件(一句话集成, 超级易用)(http://www.code4app.com/thread-29885-1-1.html...

sunnyaigd ⋅ 05/22 ⋅ 0

iOS小白点效果、打地鼠游戏、轮播效果、画板、富文本编辑器等源码

iOS精选源码 美团外卖商家点菜页面(http://www.code4app.com/thread-29383-1-1.html) 板书录制演示程序(http://www.code4app.com/thread-29384-1-1.html) 分类轮播、直播间礼物列表轮播 -- O...

sunnyaigd ⋅ 04/24 ⋅ 0

一样的iOS开发程序员为什么有人4k有人40k?

前言 移动开发真正火起来其实就是最近这几年,iOS 开发技术因为发展也就才这么几年,所以值得做的事情还有很多,这就造成了每年苹果的 WWDC 都会推出一堆新的特性和 API。整体上来说,这对业...

原来是泽镜啊 ⋅ 05/16 ⋅ 0

面试官自述:面向高级开发人员的iOS面试问题

当您准备进行技术性iOS面试时,了解您可能会询问哪些主题以及经验丰富的iOS开发人员期望什么是非常重要的。 这是许多硅谷公司用来衡量iOS候选人资历水平的一系列问题。 这些问题涉及iOS开发的...

菇哒微课 ⋅ 04/26 ⋅ 0

iOS三维菜单、调试工具、封装通讯录、网络框架、多种控件和动画等源码

iOS精选源码 一个调用系统通讯录和获取通讯录所有联系人的封装(http://www.code4app.com/thread-29726-1-1.html) ios scrollview嵌套tableview同向滑动(初级、进阶), 支持OC / Swift(http...

sunnyaigd ⋅ 05/15 ⋅ 0

Keep the Screen from Locking(阻止屏幕自动上锁)

在ios设备中,如果ios设备一段时间中没收到touch事件,ios设备就会自动锁定,但是在玩游戏时候可能会某段时间不触发touch时间,这时候就会锁定,而这并不是我们所想要的,那么我们可以设置 ...

小曼Study ⋅ 04/09 ⋅ 0

苹果与微信“短兵相接” “神仙打架”不能让用户买单

苹果与微信此次“短兵相接”,更多反映出两大巨头关于游戏规则的一场“暗战”。即便如此,也绝不能将绑架用户利益、通过随意更改产品功能,作为自己占领高地的“撒手锏”。无论苹果还是微信,...

六库科技 ⋅ 06/08 ⋅ 0

iOS自定义弹出视图、收音机APP、图片涂鸦、加载刷新、文件缓存等源码

iOS精选源码 一款优秀的 聆听夜空FM 源码(http://www.code4app.com/thread-14546-1-1.html) zhPopupController 简单快捷弹出自定义视图(http://www.code4app.com/thread-14861-1-1.html) WHS......

sunnyaigd ⋅ 06/04 ⋅ 0

如何判断你是合格的高级iOS开发工程师?

前言 随着移动互联网的高速发展泄洪而来,有意学习移动开发的人越来越多了,竞争也是越来越大,需要学习的东西很多。如何才能在激烈的移动开发者竞争中一枝独秀,成为一名真正合格的高级iOS...

_小迷糊 ⋅ 05/26 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

vim编辑模式、命令模式

编辑模式 vim要从一般模式进入编辑模式只要按字母 i 、I、a、A、o、O键就可以了 要从编辑模式回到一般模式按键盘上的Esc键即可。 按键 作用 i 在当前字符前插入 I 在光标所在行的行首插入 o ...

黄昏残影 ⋅ 24分钟前 ⋅ 0

OSChina 周五乱弹 —— 如果有一天不当程序员了

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @guanglun :分享off的单曲《我唱情歌给你听》 《我唱情歌给你听》- off 手机党少年们想听歌,请使劲儿戳(这里) @小小编辑 :#如果不做程序...

小小编辑 ⋅ 30分钟前 ⋅ 4

从 Confluence 5.3 及其早期版本中恢复空间

如果你需要从 Confluence 5.3 及其早期版本中的导出文件恢复到晚于 Confluence 5.3 的 Confluence 中的话。你可以使用临时的 Confluence 空间安装,然后将这个 Confluence 安装实例升级到你现...

honeymose ⋅ 今天 ⋅ 0

Java8新增的DateTimeFormatter与SimpleDateFormat的区别

两者最大的区别是,Java8的DateTimeFormatter也是线程安全的,而SimpleDateFormat并不是线程安全。 在并发环境下使用SimpleDateFormat 为了能够在多线程环境下使用SimpleDateFormat,有这三种...

人觉非常君 ⋅ 今天 ⋅ 0

多线程如何控制执行顺序

线程的生命周期说明: 当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态,在线程的生命周期中,它要经过新建(New)、就绪(Runnable)、运行(Running)、...

MarinJ_Shao ⋅ 今天 ⋅ 0

用ZBLOG2.3博客写读书笔记网站能创造今日头条的辉煌吗?

最近两年,著名的自媒体网站今日头条可以说是火得一塌糊涂,虽然从目前来看也遇到了一点瓶颈,毕竟发展到了一定的规模,继续增长就更加难了,但如今的今日头条规模和流量已经非常大了。 我们...

原创小博客 ⋅ 今天 ⋅ 0

MyBatis四大核心概念

本文讲解 MyBatis 四大核心概念(SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession、Mapper)。 MyBatis 作为互联网数据库映射工具界的“上古神器”,训有四大“神兽”,谓之:Sql...

waylau ⋅ 今天 ⋅ 0

以太坊java开发包web3j简介

web3j(org.web3j)是Java版本的以太坊JSON RPC接口协议封装实现,如果需要将你的Java应用或安卓应用接入以太坊,或者希望用java开发一个钱包应用,那么用web3j就对了。 web3j的功能相当完整...

汇智网教程 ⋅ 今天 ⋅ 0

2个线程交替打印100以内的数字

重点提示: 线程的本质上只是一个壳子,真正的逻辑其实在“竞态条件”中。 举个例子,比如本题中的打印,那么在竞态条件中,我只需要一个方法即可; 假如我的需求是2个线程,一个+1,一个-1,...

Germmy ⋅ 今天 ⋅ 0

Django第一期

安装Django 去https://www.djangoproject.com/download/ 下载最新版的Django,然后解压放到Anaconda\Lib\site-packages目录下,然后cmd进入此目录,输入安装命令: python setup.py install ...

大不了敲一辈子代码 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部