ข้ามไปยังเนื้อหาหลัก

iOS SDK - ยอมรับการชำระเงิน

เรียนรู้วิธีการยอมรับการชำระเงินในแอปพลิเคชัน iOS ของคุณโดยใช้ Omise iOS SDK คู่มือนี้ครอบคลุมการสร้างการเรียกเก็บเงิน การจัดการการตรวจสอบสิทธิ์ 3D Secure และการนำไปใช้ในการไหลการชำระเงินต่างๆ

ภาพรวม

Omise iOS SDK มีอินเตอร์เฟซ Swift และ Objective-C แบบเนทีฟสำหรับยอมรับการชำระเงินในแอปพลิเคชัน iOS SDK นี้จัดการ:

  • Tokenization ของข้อมูลการชำระเงิน
  • ขั้นตอนการตรวจสอบสิทธิ์ 3D Secure
  • การรวมเอกสารรับรอง Apple Pay
  • ความสามารถในการสแกนบัตร
  • UI การเลือกวิธีการชำระเงิน

ฟีเจอร์หลัก

  • การใช้งาน iOS แบบเนทีฟ - สร้างด้วย Swift เพื่อประสิทธิภาพที่ดีที่สุด
  • การสร้าง Token ที่ปลอดภัย - Tokenization ฝั่งไคลเอนต์โดยไม่มีภาระการปฏิบัติตามข้อกำหนด PCI
  • การสนับสนุน 3D Secure 2.0 - การจัดการการตรวจสอบสิทธิ์ที่ราบรื่น
  • พร้อมใช้ Apple Pay - การสนับสนุน Apple Pay แบบในตัว
  • UI ที่ปรับแต่งได้ - แบบฟอร์มการชำระเงินที่สร้างไว้หรือการใช้งานแบบกำหนดเอง
  • การสนับสนุนออฟไลน์ - คิวการชำระเงินเพื่อการประมวลผลในภายหลัง

ข้อกำหนดเบื้องต้น

ก่อนที่จะใช้งานการยอมรับการชำระเงิน:

  1. ทำการติดตั้ง SDK เสร็จสิ้น (ดู Developer Tools > iOS SDK)
  2. กำหนดค่าคีย์สาธารณะของคุณ
  3. ตั้งค่าแบ็กเอนด์ของคุณเพื่อสร้างการเรียกเก็บเงิน
  4. ทดสอบด้วยข้อมูลประจำตัวพัฒนา

ภาพรวมการไหล iOS

ขั้นตอนการชำระเงิน iOS ทั่วไป:

User enters card details

SDK tokenizes card (client-side)

Token sent to your backend

Backend creates charge with token

3D Secure authentication (if required)

Payment completed

การสร้างการเรียกเก็บเงินพื้นฐาน

ขั้นตอนที่ 1: เก็บข้อมูลบัตร

import OmiseSDK

class PaymentViewController: UIViewController {

func processPayment(amount: Int64, currency: String) {
// Create a payment request
let request = OmiseTokenRequest(
name: "John Appleseed",
number: "4242424242424242",
expirationMonth: 12,
expirationYear: 2025,
securityCode: "123"
)

// Create token
let client = OmiseSDKClient(publicKey: "pkey_test_123")

client.send(request) { [weak self] result in
switch result {
case .success(let token):
self?.createCharge(with: token.id, amount: amount, currency: currency)
case .failure(let error):
self?.handleError(error)
}
}
}

func createCharge(with tokenId: String, amount: Int64, currency: String) {
// Send to your backend
let parameters: [String: Any] = [
"token": tokenId,
"amount": amount,
"currency": currency,
"return_uri": "myapp://payment/complete"
]

// Make API call to your backend
APIClient.shared.post("/charges", parameters: parameters) { result in
switch result {
case .success(let charge):
self.handleChargeResult(charge)
case .failure(let error):
self.handleError(error)
}
}
}
}

ขั้นตอนที่ 2: ใช้แบบฟอร์มการชำระเงินที่สร้างไว้

import OmiseSDK

class CheckoutViewController: UIViewController {

func presentPaymentForm() {
let capability = loadCapability() // Load from your backend

let paymentConfiguration = PaymentCreatorConfiguration(
publicKey: "pkey_test_123",
amount: 100000, // 1,000.00 in smallest currency unit
currency: .thb,
capability: capability
)

let paymentController = PaymentCreatorController.makePaymentCreatorController(
configuration: paymentConfiguration
) { [weak self] result in
self?.handlePaymentResult(result)
}

present(paymentController, animated: true)
}

func handlePaymentResult(_ result: Result<PaymentToken, Error>) {
switch result {
case .success(let token):
// Send token to backend to create charge
createChargeOnBackend(token: token)

case .failure(let error):
showError(error.localizedDescription)
}
}

func createChargeOnBackend(token: PaymentToken) {
let parameters: [String: Any] = [
"source": token.id,
"amount": 100000,
"currency": "THB",
"return_uri": "myapp://payment/complete"
]

APIClient.shared.post("/charges", parameters: parameters) { result in
// Handle charge creation result
self.processChargeResponse(result)
}
}
}

การจัดการการตรวจสอบสิทธิ์ 3D Secure

การใช้งาน 3D Secure Flow

import OmiseSDK
import SafariServices

class PaymentProcessor {

var authorizingViewController: SFSafariViewController?

func handleChargeResponse(_ charge: Charge) {
guard charge.status != .successful else {
// Payment completed without 3DS
showSuccess()
return
}

// Check if 3D Secure authentication is required
if charge.status == .pending,
let authorizeURL = charge.authorizeURL {
present3DSecure(url: authorizeURL)
}
}

func present3DSecure(url: URL) {
let safariVC = SFSafariViewController(url: url)
safariVC.delegate = self
authorizingViewController = safariVC

present(safariVC, animated: true)
}

// Handle return from 3D Secure
func application(_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {

guard url.scheme == "myapp",
url.host == "payment" else {
return false
}

// Close Safari view controller
authorizingViewController?.dismiss(animated: true) {
// Verify payment status with backend
self.verifyPaymentStatus()
}

return true
}

func verifyPaymentStatus() {
// Check charge status from your backend
APIClient.shared.get("/charges/verify") { result in
switch result {
case .success(let charge):
if charge.status == .successful {
self.showSuccess()
} else if charge.status == .failed {
self.showError("Payment failed")
}
case .failure(let error):
self.showError(error.localizedDescription)
}
}
}
}

extension PaymentProcessor: SFSafariViewControllerDelegate {
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
// User cancelled 3DS
showError("Authentication cancelled")
}
}

กำหนดค่า URL Scheme

ใน Info.plist ของคุณ:

<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>myapp</string>
</array>
<key>CFBundleURLName</key>
<string>com.mycompany.myapp</string>
</dict>
</array>

การชำระเงินด้วยบัตรที่บันทึกไว้

การเรียกเก็บเงินจากบัตรที่บันทึกไว้

class SavedCardPayment {

func chargeWithSavedCard(customerId: String, cardId: String, amount: Int64) {
let parameters: [String: Any] = [
"customer": customerId,
"card": cardId,
"amount": amount,
"currency": "THB",
"return_uri": "myapp://payment/complete"
]

APIClient.shared.post("/charges", parameters: parameters) { result in
switch result {
case .success(let charge):
self.handleChargeResponse(charge)
case .failure(let error):
self.handleError(error)
}
}
}

func displaySavedCards(customerId: String) {
APIClient.shared.get("/customers/\(customerId)/cards") { result in
switch result {
case .success(let cards):
self.showCardSelection(cards)
case .failure(let error):
self.handleError(error)
}
}
}

func showCardSelection(_ cards: [Card]) {
let alert = UIAlertController(
title: "Select Card",
message: "Choose a payment method",
preferredStyle: .actionSheet
)

for card in cards {
let action = UIAlertAction(
title: "\(card.brand) •••• \(card.lastDigits)",
style: .default
) { _ in
self.chargeSelectedCard(card)
}
alert.addAction(action)
}

alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))
present(alert, animated: true)
}
}

การบันทึกบัตรใหม่

func saveCardForFutureUse(customerId: String) {
let request = OmiseTokenRequest(
name: "John Appleseed",
number: "4242424242424242",
expirationMonth: 12,
expirationYear: 2025,
securityCode: "123"
)

let client = OmiseSDKClient(publicKey: "pkey_test_123")

client.send(request) { result in
switch result {
case .success(let token):
self.attachCardToCustomer(customerId: customerId, tokenId: token.id)
case .failure(let error):
self.handleError(error)
}
}
}

func attachCardToCustomer(customerId: String, tokenId: String) {
let parameters = ["card": tokenId]

APIClient.shared.post("/customers/\(customerId)/cards", parameters: parameters) { result in
switch result {
case .success:
self.showSuccess("Card saved successfully")
case .failure(let error):
self.handleError(error)
}
}
}

แบบฟอร์มการชำระเงินแบบกำหนดเอง

สร้าง UI แบบกำหนดเอง

import OmiseSDK

class CustomPaymentForm: UIViewController {

@IBOutlet weak var cardNumberField: UITextField!
@IBOutlet weak var expiryField: UITextField!
@IBOutlet weak var cvvField: UITextField!
@IBOutlet weak var cardholderField: UITextField!
@IBOutlet weak var payButton: UIButton!

let client = OmiseSDKClient(publicKey: "pkey_test_123")

@IBAction func payButtonTapped(_ sender: UIButton) {
guard validateForm() else {
showError("Please fill all required fields")
return
}

createToken()
}

func validateForm() -> Bool {
guard let number = cardNumberField.text, !number.isEmpty,
let expiry = expiryField.text, !expiry.isEmpty,
let cvv = cvvField.text, !cvv.isEmpty,
let name = cardholderField.text, !name.isEmpty else {
return false
}

// Validate card number using Luhn algorithm
let isValid = OmiseCardValidator.validate(number: number)
return isValid
}

func createToken() {
let expiry = parseExpiry(expiryField.text ?? "")

let request = OmiseTokenRequest(
name: cardholderField.text ?? "",
number: cardNumberField.text ?? "",
expirationMonth: expiry.month,
expirationYear: expiry.year,
securityCode: cvvField.text ?? ""
)

showLoading()

client.send(request) { [weak self] result in
self?.hideLoading()

switch result {
case .success(let token):
self?.processPayment(with: token.id)
case .failure(let error):
self?.showError(error.localizedDescription)
}
}
}

func parseExpiry(_ text: String) -> (month: Int, year: Int) {
let components = text.components(separatedBy: "/")
let month = Int(components[0].trimmingCharacters(in: .whitespaces)) ?? 1
let year = Int(components[1].trimmingCharacters(in: .whitespaces)) ?? 2025
return (month, year)
}
}

การจัดรูปแบบหมายเลขบัตร

extension CustomPaymentForm: UITextFieldDelegate {

func textField(_ textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool {

guard textField == cardNumberField else {
return true
}

let currentText = textField.text ?? ""
let newText = (currentText as NSString).replacingCharacters(in: range, with: string)
let digitsOnly = newText.components(separatedBy: .decimalDigits.inverted).joined()

// Limit to 16 digits
guard digitsOnly.count <= 16 else {
return false
}

// Format with spaces
let formatted = formatCardNumber(digitsOnly)
textField.text = formatted

// Update card brand icon
updateCardBrandIcon(digitsOnly)

return false
}

func formatCardNumber(_ number: String) -> String {
var formatted = ""
for (index, char) in number.enumerated() {
if index > 0 && index % 4 == 0 {
formatted += " "
}
formatted.append(char)
}
return formatted
}

func updateCardBrandIcon(_ number: String) {
let brand = OmiseCardBrand.detect(from: number)
// Update UI with card brand icon
cardBrandImageView.image = UIImage(named: brand.rawValue)
}
}

การรวม Apple Pay

การใช้ Apple Pay

import PassKit

class ApplePayProcessor: NSObject {

func startApplePay(amount: Decimal, currency: String) {
let request = PKPaymentRequest()
request.merchantIdentifier = "merchant.com.mycompany.myapp"
request.supportedNetworks = [.visa, .masterCard, .amex]
request.merchantCapabilities = .capability3DS
request.countryCode = "TH"
request.currencyCode = currency

let item = PKPaymentSummaryItem(
label: "Total",
amount: NSDecimalNumber(decimal: amount)
)
request.paymentSummaryItems = [item]

guard let controller = PKPaymentAuthorizationController(paymentRequest: request) else {
return
}

controller.delegate = self
controller.present()
}
}

extension ApplePayProcessor: PKPaymentAuthorizationControllerDelegate {

func paymentAuthorizationController(
_ controller: PKPaymentAuthorizationController,
didAuthorizePayment payment: PKPayment,
handler completion: @escaping (PKPaymentAuthorizationResult) -> Void
) {
// Convert Apple Pay token to Omise token
processApplePayToken(payment.token) { result in
switch result {
case .success:
completion(PKPaymentAuthorizationResult(status: .success, errors: nil))
case .failure(let error):
let errors = [error]
completion(PKPaymentAuthorizationResult(status: .failure, errors: errors))
}
}
}

func paymentAuthorizationControllerDidFinish(
_ controller: PKPaymentAuthorizationController
) {
controller.dismiss()
}

func processApplePayToken(_ token: PKPaymentToken,
completion: @escaping (Result<Void, Error>) -> Void) {
let paymentData = token.paymentData

// Send to backend to create Omise token and charge
APIClient.shared.post("/apple-pay/process", parameters: [
"payment_data": paymentData.base64EncodedString()
]) { result in
completion(result.map { _ in () })
}
}
}

การจัดการข้อผิดพลาด

การจัดการข้อผิดพลาดที่ครอบคลุม

enum PaymentError: LocalizedError {
case tokenizationFailed(Error)
case chargeFailed(String)
case authenticationFailed
case networkError(Error)
case invalidCard
case insufficientFunds
case cardDeclined

var errorDescription: String? {
switch self {
case .tokenizationFailed(let error):
return "Failed to process card: \(error.localizedDescription)"
case .chargeFailed(let message):
return message
case .authenticationFailed:
return "Payment authentication failed"
case .networkError:
return "Network error. Please check your connection."
case .invalidCard:
return "Invalid card information"
case .insufficientFunds:
return "Insufficient funds"
case .cardDeclined:
return "Card declined by bank"
}
}
}

class PaymentErrorHandler {

func handleError(_ error: Error) {
if let omiseError = error as? OmiseError {
handleOmiseError(omiseError)
} else {
showGenericError(error)
}
}

func handleOmiseError(_ error: OmiseError) {
switch error.code {
case .invalidCard:
showError("Please check your card information")
case .insufficientFunds:
showError("Insufficient funds on card")
case .stolenOrLostCard:
showError("Card reported as lost or stolen")
case .failedProcessing:
showError("Payment processing failed")
default:
showError(error.message)
}

// Log for analytics
logError(error)
}

func showError(_ message: String) {
let alert = UIAlertController(
title: "Payment Error",
message: message,
preferredStyle: .alert
)
alert.addAction(UIAlertAction(title: "OK", style: .default))

// Present alert
if let topVC = UIApplication.topViewController() {
topVC.present(alert, animated: true)
}
}
}

กรณีการใช้งานทั่วไป

การชำระเงินสมาชิกซื้อ

class SubscriptionPayment {

func processSubscriptionPayment(plan: String, customerId: String) {
// First payment with card
let parameters: [String: Any] = [
"customer": customerId,
"amount": 99900, // 999.00 THB
"currency": "THB",
"description": "Monthly \(plan) subscription",
"metadata": [
"plan": plan,
"type": "subscription"
]
]

APIClient.shared.post("/charges", parameters: parameters) { result in
switch result {
case .success(let charge):
if charge.status == .successful {
// Create schedule on backend
self.createRecurringSchedule(customerId: customerId, plan: plan)
}
case .failure(let error):
self.handleError(error)
}
}
}

func createRecurringSchedule(customerId: String, plan: String) {
let parameters: [String: Any] = [
"customer": customerId,
"amount": 99900,
"period": "month",
"description": "\(plan) subscription"
]

APIClient.shared.post("/schedules", parameters: parameters) { result in
self.handleScheduleCreation(result)
}
}
}

การซื้อแบบครั้งเดียว

class OneTimePurchase {

func processCheckout(items: [CartItem]) {
let total = items.reduce(0) { $0 + $1.price }

// Show payment form
showPaymentForm(amount: total) { tokenId in
self.createOrder(items: items, tokenId: tokenId)
}
}

func createOrder(items: [CartItem], tokenId: String) {
let orderItems = items.map { [
"id": $0.id,
"quantity": $0.quantity
]}

let parameters: [String: Any] = [
"token": tokenId,
"items": orderItems,
"return_uri": "myapp://order/complete"
]

APIClient.shared.post("/orders", parameters: parameters) { result in
self.handleOrderCreation(result)
}
}
}

การชำระเงินหลายสกุลเงิน

class MultiCurrencyCheckout {

func processInternationalPayment(amount: Int64, currency: String) {
// Convert currency if needed
convertCurrency(amount: amount, from: "THB", to: currency) { convertedAmount in
self.createPayment(amount: convertedAmount, currency: currency)
}
}

func createPayment(amount: Int64, currency: String) {
let parameters: [String: Any] = [
"amount": amount,
"currency": currency,
"description": "International purchase"
]

showPaymentForm(parameters: parameters)
}
}

แนวทางที่ดีที่สุด

ความปลอดภัย

  1. ไม่เคยเก็บข้อมูลบัตร

    // ✅ Good - Use tokens
    let token = createToken(from: cardData)
    sendToBackend(token: token.id)

    // ❌ Bad - Don't store raw card data
    UserDefaults.standard.set(cardNumber, forKey: "card")
  2. ตรวจสอบความถูกต้องบนไคลเอนต์และเซิร์ฟเวอร์

    func validateCard() -> Bool {
    guard OmiseCardValidator.validate(number: cardNumber) else {
    return false
    }

    guard OmiseCardValidator.validateCVV(cvv, for: cardBrand) else {
    return false
    }

    return true
    }
  3. ใช้การสื่อสารที่ปลอดภัย

    let configuration = URLSessionConfiguration.default
    configuration.tlsMinimumSupportedProtocolVersion = .TLSv12

ประสบการณ์ผู้ใช้

  1. แสดงสถานะการโหลดที่ชัดเจน

    func showPaymentProgress() {
    let hud = MBProgressHUD.showAdded(to: view, animated: true)
    hud.label.text = "Processing payment..."
    hud.detailsLabel.text = "Please wait"
    }
  2. ให้ข้อมูลการชำระเงิน

    func showPaymentSuccess() {
    let alert = UIAlertController(
    title: "Payment Successful",
    message: "Your payment has been processed",
    preferredStyle: .alert
    )

    // Haptic feedback
    let generator = UINotificationFeedbackGenerator()
    generator.notificationOccurred(.success)
    }
  3. จัดการปัญหาเครือข่าย

    func retryPayment() {
    let alert = UIAlertController(
    title: "Connection Issue",
    message: "Unable to process payment. Retry?",
    preferredStyle: .alert
    )

    alert.addAction(UIAlertAction(title: "Retry", style: .default) { _ in
    self.processPayment()
    })

    alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))
    present(alert, animated: true)
    }

ประสิทธิภาพ

  1. เพิ่มประสิทธิภาพการสร้าง Token

    private var tokenCreationTask: URLSessionTask?

    func createToken() {
    tokenCreationTask?.cancel()

    tokenCreationTask = client.send(request) { result in
    // Handle result
    }
    }
  2. วิธีการชำระเงินแคช

    private var cachedCards: [Card]?
    private var cacheTimestamp: Date?

    func loadSavedCards(forceRefresh: Bool = false) {
    if !forceRefresh,
    let cached = cachedCards,
    let timestamp = cacheTimestamp,
    Date().timeIntervalSince(timestamp) < 300 {
    displayCards(cached)
    return
    }

    fetchCardsFromServer()
    }

การแก้ไขปัญหา

ปัญหาทั่วไป

Token Creation Fails

// Check public key configuration
let client = OmiseSDKClient(publicKey: "pkey_test_123")

// Verify card details
print("Card number valid: \(OmiseCardValidator.validate(number: number))")
print("CVV valid: \(OmiseCardValidator.validateCVV(cvv, for: brand))")

3D Secure Not Working

// Ensure return URI is registered
// Check Info.plist for URL scheme
// Verify authorization URL is valid

if let url = charge.authorizeURL {
print("Auth URL: \(url)")
present3DSecure(url: url)
}

Apple Pay Not Available

if PKPaymentAuthorizationController.canMakePayments() {
if PKPaymentAuthorizationController.canMakePayments(
usingNetworks: [.visa, .masterCard]
) {
showApplePayButton()
}
} else {
print("Apple Pay not available on this device")
}

โหมดดีบัก

#if DEBUG
extension OmiseSDKClient {
func enableDebugMode() {
// Log all requests
self.logger = { request in
print("API Request: \(request)")
}
}
}
#endif

คำถามที่พบบ่อย

คำถามทั่วไป

Q: ฉันต้องจัดการการปฏิบัติตามข้อกำหนด PCI สำหรับแอป iOS หรือไม่?

A: ไม่ Omise iOS SDK tokenizes ข้อมูลบัตรฝั่งไคลเอนต์ก่อนที่จะถึงเซิร์ฟเวอร์ของคุณ ซึ่งช่วยลดข้อกำหนด PCI อย่างมาก อย่างไรก็ตาม คุณควรปฏิบัติตามแนวปฏิบัติความปลอดภัยที่ดีที่สุด

Q: ฉันสามารถยอมรับการชำระเงินออฟไลน์ได้หรือไม่?

A: การสนับสนุนบางส่วน คุณสามารถเก็บข้อมูลบัตรออฟไลน์และสร้าง token ในภายหลัง แต่การเรียกเก็บเงินจริงต้องใช้การเชื่อมต่ออินเทอร์เน็ตเพื่อการอนุมัติ

Q: เวอร์ชัน iOS ที่รองรับคืออะไร?

A: Omise iOS SDK รองรับ iOS 12.0 และเวอร์ชันที่ใหม่กว่า เพื่อผลลัพธ์ที่ดีที่สุดและฟีเจอร์ล่าสุด เราแนะนำให้รองรับ iOS 14.0 ขึ้นไป

Q: ฉันจะทดสอบการชำระเงินในการพัฒนาได้อย่างไร?

A: ใช้หมายเลขบัตรทดสอบ (4242 4242 4242 4242) พร้อมวันหมดอายุในอนาคตใดก็ได้ และ CVV 3 หลักใดก็ได้ ใช้คีย์สาธารณะทดสอบของคุณ (pkey_test_xxx) สำหรับการทดสอบ

Q: ฉันสามารถปรับแต่ง UI แบบฟอร์มการชำระเงินได้หรือไม่?

A: ใช่ คุณสามารถใช้ตัวควบคุมการชำระเงินที่สร้างไว้ร่วมกับตัวเลือกการปรับแต่ง หรือสร้าง UI ของคุณเองและใช้ SDK สำหรับ tokenization เท่านั้น

Q: โทเค็นมีอายุเท่านาน?

A: โทเค็นหมดอายุหลังจากใช้งานเพื่อสร้างการเรียกเก็บเงินหรือแนบกับลูกค้า พวกเขาไม่สามารถนำกลับมาใช้ได้

คำถามเกี่ยวกับ 3D Secure

Q: 3D Secure จำเป็นสำหรับการชำระเงินทั้งหมดหรือไม่?

A: ไม่ใช่ทุกการชำระเงิน ขึ้นอยู่กับผู้ออกบัตร จำนวน และการตั้งค่าผู้ค้า การใช้งานของคุณควรจัดการทั้งการไหลแบบนี้

Q: จะเกิดอะไรขึ้นหากผู้ใช้ยกเลิก 3D Secure?

A: การชำระเงินล้มเหลวและสถานะการเรียกเก็บเงินยังคงรอดำเนินการหรือล้มเหลว จัดการสิ่งนี้ในตัวจำหน่าย Safari view controller

Q: ฉันสามารถทดสอบการตรวจสอบสิทธิ์ 3D Secure ได้หรือไม่?

A: ใช่ ใช้บัตรทดสอบ 4000000000003063 เพื่อจำลองการตรวจสอบสิทธิ์ 3D Secure ในโหมดทดสอบ

Q: ฉันจะจัดการหมดเวลา 3D Secure ได้อย่างไร?

A: ใช้การตรวจจับหมดเวลาในตัวจำหน่ายการตรวจสอบสิทธิ์ของคุณและให้ผู้ใช้มีตัวเลือกในการลองใหม่หรือยกเลิกการชำระเงิน

คำถามเกี่ยวกับ Apple Pay

Q: ฉันต้องการการอนุมัติพิเศษสำหรับ Apple Pay หรือไม่?

A: ใช่ คุณต้องมีบัญชี Apple Developer, การกำหนดค่า Merchant ID และใบรับรองการประมวลผลการชำระเงิน ดูเอกสาร Apple Pay

Q: ฉันสามารถใช้ Apple Pay ในโหมดทดสอบได้หรือไม่?

A: ใช่ แต่คุณต้องกำหนดค่าใบรับรองทดสอบและใช้ข้อมูลประจำตัวสภาแวดล้อม Sandbox

Q: อะไรคือความแตกต่างระหว่าง Apple Pay และการชำระเงินด้วยบัตร?

A: Apple Pay ใช้ข้อมูลบัตรแบบ tokenized และให้ความปลอดภัยที่เพิ่มขึ้น ขั้นตอนการใช้งานแตกต่างกัน แต่การสร้างการเรียกเก็บเงินแบ็กเอนด์ก็เหมือนกัน

ทรัพยากรที่เกี่ยวข้อง

ขั้นตอนถัดไป