Pay Using Card Information
Ensure your card method connection is set to Server to Server in the MoneyHash dashboard.
Using your account Public API Key on the MoneyHashSDK
class instance, you can access the functionality to collect card data and process payments.
Initialize MoneyHashSDK
Before starting, initialize the MoneyHash SDK with your Public API Key:
import MoneyHashSDK
let moneyHashSDK = MoneyHashSDKBuilder()
.setPublicKey("<account_public_api_key>")
.build()
Replace "<account_public_api_key>"
with your actual Public API Key from MoneyHash.
Collect Card Data
Once the card form is set up (you can follow the steps here), you can collect card data using the collect()
method from the CardForm
instance:
import MoneyHashSDK
import Foundation
class CardFormViewModel: ObservableObject {
@Published var cardForm: CardForm? // Assume this is set up as per the linked documentation
func collectCardData() async throws -> VaultData? {
do {
return try await cardForm?.collect()
} catch {
print("Error collecting card data: \(error)")
throw error
}
}
}
Note: Make sure the card form is properly set up and rendered before attempting to collect card data.
Pay
Once you've collected the card data, you can process the payment using the pay()
method:
import Foundation
class CardFormViewModel: ObservableObject {
@Published var cardForm: CardForm? // Assume this is set up as per the linked documentation
func processPayment(intentId: String, saveCard: Bool, billingData: [String: String]?, shippingData: [String: String]?) async throws {
do {
guard let cardData = try await collectCardData() else { return }
let intentDetails = try await cardForm?.pay(
intentId: intentId,
cardData: cardData,
saveCard: saveCard,
billingData: billingData,
shippingData: shippingData
)
print("Payment successful: \(String(describing: intentDetails))")
} catch {
print("Payment failed: \(error)")
throw error
}
}
}
Here, the pay()
method processes the payment using the provided card data, intent ID, and optional billing/shipping data for reference look at the basics docs.
Note:
saveCard
Passing
saveCard: true
will allow MoneyHash to tokenize and save the card for future use. Make sure your intent is created with"allow_tokenize_card": true
for tokenization to work.
Complete Example
Here’s a complete SwiftUI-based example that integrates the steps for collecting card data and processing payments:
import SwiftUI
import MoneyHashSDK
@available(iOS 15.0, *)
class CardFormViewModel: ObservableObject {
@Published var cardForm: CardForm?
init() {
setupCardForm()
}
private func setupCardForm() {
self.cardForm = CardFormBuilder()
.setCardNumberField { [weak self] state in
print("Card Number Field State: \(state)")
}
.setCVVField { [weak self] state in
print("CVV Field State: \(state)")
}
.setCardHolderNameField { [weak self] state in
print("Card Holder Name Field State: \(state)")
}
.setExpireMonthField { [weak self] state in
print("Expire Month Field State: \(state)")
}
.setExpireYearField { [weak self] state in
print("Expire Year Field State: \(state)")
}
.setCardBrandChangeHandler { [weak self] brand in
print("Card Brand Changed: \(brand)")
}.build()
}
func handlePayment(intentId: String) async {
do {
guard let cardData = try await collectCardData() else { return }
let intentDetails = try await cardForm?.pay(
intentId: intentId,
cardData: cardData,
saveCard: true, // Set to true to save the card (optional)
billingData: ["address": "123 Main St", "city": "New York"], // Optional
shippingData: ["address": "456 Elm St", "city": "Boston"] // Optional
)
print("Payment Successful: \(String(describing: intentDetails))")
} catch {
print("Payment Error: \(error)")
}
}
private func collectCardData() async throws -> VaultData? {
return try await cardForm?.collect()
}
}
@available(iOS 15.0, *)
struct CardFormView: View {
@StateObject var viewModel = CardFormViewModel()
var body: some View {
VStack(spacing: 16) {
SecureTextField(cardFormCollector: viewModel.cardForm!, type: .cardHolderName) {
Text("Cardholder Name")
.foregroundColor(.gray)
}
.textFieldStyle()
SecureTextField(cardFormCollector: viewModel.cardForm!, type: .cardNumber) {
Text("Card Number")
.foregroundColor(.gray)
}
.textFieldStyle()
HStack(spacing: 8) {
SecureTextField(cardFormCollector: viewModel.cardForm!, type: .expireMonth) {
Text("MM")
.foregroundColor(.gray)
}
.textFieldStyle()
SecureTextField(cardFormCollector: viewModel.cardForm!, type: .expireYear) {
Text("YY")
.foregroundColor(.gray)
}
.textFieldStyle()
SecureTextField(cardFormCollector: viewModel.cardForm!, type: .cvv) {
Text("CVV")
.foregroundColor(.gray)
}
.textFieldStyle()
}
Button("Pay") {
Task {
await viewModel.handlePayment(intentId: "<intent_id>")
}
}
}
.padding()
}
}
@available(iOS 15.0, *)
extension View {
func textFieldStyle() -> some View {
self
.padding()
.background(Color(UIColor.systemGray6))
.cornerRadius(8)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(Color(UIColor.separator), lineWidth: 1)
)
}
}
Updated about 1 month ago