Common Reasons for Payment Screen Not Appearing
- SDK Initialization First, verify the SDK is properly initialized. Add this before calling
makeSquareTransaction
:
// Add at app startup or before payments
func initializeSDK() {
do {
try MobilePaymentsSDK.shared.initialize(applicationLaunchOptions: nil)
print("Square SDK initialized successfully")
} catch {
print("Failed to initialize Square SDK: \(error)")
}
}
- Delegate Implementation Ensure your view controller properly implements
PaymentManagerDelegate
:
class YourViewController: UIViewController, PaymentManagerDelegate {
// Required delegate methods
func paymentManager(_ paymentManager: PaymentManager, didCompletePayment result: PaymentResult) {
// Handle successful payment
}
func paymentManager(_ paymentManager: PaymentManager, didFailPayment error: Error) {
// Handle payment failure
}
func paymentManagerDidCancel(_ paymentManager: PaymentManager) {
// Handle payment cancellation
}
}
- Modified Payment Parameters Here’s the complete
makePaymentParameters
function with all required fields:
func makePaymentParameters(amountMoney: Money) -> PaymentParameters {
return PaymentParameters(
idempotencyKey: UUID().uuidString,
amountMoney: amountMoney,
// Add these required parameters
autocomplete: false,
locationId: "YOUR_LOCATION_ID",
customerId: nil, // Optional
notes: notes, // Optional
statementDescription: nil, // Optional
metadata: nil // Optional
)
}
- Updated Transaction Method Here’s the corrected
makeSquareTransaction
method with error handling:
func makeSquareTransaction(
centsAmount: Int,
notes: String,
from viewController: UIViewController
) {
// Verify SDK initialization
guard MobilePaymentsSDK.shared.isInitialized else {
print("Square SDK not initialized")
return
}
// Verify delegate
guard let vc = viewController as? PaymentManagerDelegate else {
print("PaymentManagerDelegate is required")
return
}
// Create payment parameters
let amountMoney = Money(amount: UInt(centsAmount), currency: .USD)
let paymentParams = makePaymentParameters(amountMoney: amountMoney)
// Create prompt parameters
let paymentPromptParameters = PromptParameters(
mode: .default,
additionalMethods: .all
)
// Start payment with completion handler
DispatchQueue.main.async {
MobilePaymentsSDK.shared.paymentManager.startPayment(
paymentParams,
promptParameters: paymentPromptParameters,
from: viewController,
delegate: vc
) { result in
switch result {
case .success:
print("Payment screen presented successfully")
case .failure(let error):
print("Failed to present payment screen: \(error)")
}
}
}
}
Implementation Checklist
- Verify Info.plist Settings
<key>NSCameraUsageDescription</key>
<string>Required for card scanning</string>
<key>NSMicrophoneUsageDescription</key>
<string>Required for tap to pay</string>
<key>NSNFCReaderUsageDescription</key>
<string>Required for tap to pay</string>
- Add Required Capabilities In Xcode:
- Enable “Near Field Communication Tag Reading” capability
- Enable “Payment Processing” capability
- Usage Example
class YourViewController: UIViewController, PaymentManagerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
initializeSDK()
}
@IBAction func onPayButtonTapped(_ sender: Any) {
makeSquareTransaction(
centsAmount: 1000, // $10.00
notes: "Test payment",
from: self
)
}
// Delegate methods implementation
func paymentManager(_ paymentManager: PaymentManager, didCompletePayment result: PaymentResult) {
print("Payment completed: \(result)")
}
func paymentManager(_ paymentManager: PaymentManager, didFailPayment error: Error) {
print("Payment failed: \(error)")
}
func paymentManagerDidCancel(_ paymentManager: PaymentManager) {
print("Payment cancelled")
}
}
Debugging Steps
- Add logging to track the flow:
print("SDK Initialized: \(MobilePaymentsSDK.shared.isInitialized)")
print("Payment Parameters: \(paymentParams)")
print("View Controller: \(viewController)")
- Check for any console errors or warnings
- Verify you’re calling this on the main thread