Pay Kit is an open source software framework that allows you to accept Cash App Pay in your App. The framework provides a modules that can be used out of the box where the customer will be redirected from your checkout experience to Cash App to approve the payment before being redirected back to your App. It is composed of two SPM packages which can each be imported separately.
-
PayKit
: This is the best place to start building your app.PayKit
provides a protocol calledCashAppPayObserver
that receives updates from Pay Kit. Your checkout view controller can conform to this protocol, or you can create a dedicated observer class. -
PayKitUI
: Provides the views used across the framework. The views are provided to the user to launch a Pay Kit payment and to present the Cashtag but do not prescribe how they must be used.
The primary PayKit
framework codebase supports iOS and requires Xcode 12.0 or newer. The PayKit
framework has a Base SDK version of 13.0.
You can install Pay Kit via SPM. Create a new Xcode project and navigate to File > Swift Packages > Add Package Dependency
. Enter the url https://github.com/cashapp/cash-app-pay-ios-sdk
and tap Next. Choose the main
branch, and on the next screen, check off the packages as needed.
Add Cocoapods to your to your project. Open the Podfile
and add pod 'CashAppPayKit'
and/or pod 'CashAppPayKitUI'
and save your changes. Run pod update
and Pay Kit will now be included through Cocoapods
The CashAppPayObserver
protocol contains only one method:
func stateDidChange(to state: CashAppPayState) {
// handle state changes
}
Your implementation should switch on the state parameter and handle the appropriate state changes. Some of these possible states are for information only, but most drive the logic of your integration. The most critical states to handle are listed in the table below:
State | Description |
---|---|
ReadyToAuthorize |
Show a Cash App Pay button in your UI and call authorizeCustomerRequest() when it is tapped |
Approved |
Grants are ready for your backend to use to create a payment |
Declined |
Customer has declined the Cash App Pay authorization and must start the flow over or choose a new payment method |
The error states | |
.integrationError |
A fixable bug in your integration |
.apiError |
A degradation of Cash App Pay server APIs. Your app should temporarily hide Cash App Pay functionality |
.unexpectedError |
A bug outside the normal flow. Report this bug (and what caused it) to Cash App Developer Support |
To use Pay Kit iOS, Cash App must be able to call a URL that will redirect back to your app. The simplest way to accomplish this is via Custom URL Schemes, but if your app supports Universal Links you ca use those URLs as well.
Choose a unique scheme for your application and register it in Xcode from the Info tab of your application’s target.
You will pass a URL that uses this scheme (or a Universal Link your app handles) into the createCustomerRequest()
method that starts the authorization process.
When your app is called back by Cash App, simply post the CashAppPay.RedirectNotification
from your AppDelegate
or SceneDelegate
, and the SDK will handle the rest:
import UIKit
import PayKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
if let url = URLContexts.first?.url {
NotificationCenter.default.post(
name: CashAppPay.RedirectNotification,
object: nil,
userInfo: [UIApplication.LaunchOptionsKey.url : url]
)
}
}
}
}
When you are ready to authorize a payment using Cash App Pay,
- Instantiate the SDK with your Client ID
- The SDK defaults to point to the
production
endpoint; for development, set the endpoint tosandbox
- Add your observer to the SDK
For example, from your checkout view controller that implements the CashAppPayObserver
protocol, you can instantiate the SDK to be:
private let sandboxClientID = "YOUR_CLIENT_ID"
private lazy var sdk: CashAppPay = {
let sdk = CashAppPay(clientID: sandboxClientID, endpoint: .sandbox)
sdk.addObserver(self)
return sdk
}()
You can create a customer request as soon as you know the amount you’d like to charge or if you'd like to create an on-file payment request. You must create this request as soon as your checkout view controller loads, so that your customer can authorize the request without any delay.
To charge $5.00, your createCustomerRequest
call might look like this:
private let sandboxBrandID = "YOUR_BRAND_ID"
override func viewDidLoad() {
super.viewDidLoad()
// load view hierarchy
sdk.createCustomerRequest(
params: CreateCustomerRequestParams(
actions: [
.oneTimePayment(
scopeID: brandID,
money: Money(amount: 500, currency: .USD)
)
],
channel: .IN_APP,
redirectURL: URL(string: "tipmycap://callback")!,
referenceID: nil,
metadata: nil
)
)
}
Your Observer’s state will change to .creatingCustomerRequest
, then .readyToAuthorize
with the created CustomerRequest
struct as an associated value.
Once the SDK is in the .readyToAuthorize
state, you can store the associated CustomerRequest
and display a Cash App Pay button. When the customer taps the button, you can authorize the customer request.
Example
@objc func cashAppPayButtonTapped() {
sdk.authorizeCustomerRequest(request)
}
Your app will redirect to Cash App for authorization. When authorization is completed, your redirect URL will be called, the RedirectNotification
will post. The SDK will fetch your authorized request and return it to your Observer, as part of the change to the .approved
state.
The approved CustomerRequest
will have Grants
associated with it that can be used with Cash App’s Create Payment API. Pass those Grants to your backend and call the CreatePayment
API as a server-to-server call to complete your payment.
PayKitUI
provides an unmanaged CashAppPayButton
and a CashAppPaymentMethod
view in both UIKit and SwiftUI.
All of the views accept a SizingCategory
to dictate the preferred size of the view within your app. They also support light/dark themes by default.
We want you to use these views as-is, without any modification.
The following is an example of the CashAppPayButton
:
You can instantiate the button as follows:
let button = CashAppPayButton(size: .small, onClickHandler: {})
The following is an example of CashAppPaymentMethod
:
You can instatiate the CashAppPaymentMethod
as follows:
let paymentMethod = CashAppPaymentMethod(size: .small)
paymentMethod.cashTag = "$jack"
GitHub is our primary forum for Pay Kit. To get help, open Issues about questions, problems, or ideas.
This project is made available under the terms of a Apache 2.0 license. See the LICENSE file.
Copyright 2023 Square, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.