Create a Single-Step Payment
A single-step payment (or “Direct Sale”) is a transaction where funds are authorized and captured in one operation. This is the most common flow for retail and immediate services, where payment is processed instantly.
This guide walks you through processing a complete sale transaction using the Get Mini SDK, from creating the payment DTO to handling the authorization result.
Requirements
Before you begin, ensure you have:
- SDK initialized with environment and license via
CommonUtils - Merchant configuration from successful login (
DatosLoginResponseDTO) - PIN pad connected and initialized (received
PinpadConfigfromonInitFinished) - Delegates implemented:
RedsysBTPinpadPaymentDelegateto handle transaction results
Complete Initialize the SDK and Quick Start: Your First Sale before proceeding.
Payment Process
Step 1: Create the Payment DTO
Prepare the transaction data using PagoDTO. The amount must be specified in cents (multiply by 100):
// Import via Bridging Header: PagoDTO.h
func createPaymentData() -> PagoDTO {
let amount: Float = 15.50 // Amount in currency units
let pagoDTO = PagoDTO(
valor: Int(amount * 100), // Convert to cents: 1550
mMoneda: 978, // ISO 4217 code (978 = EUR)
nFactura: "SALE\(Int.random(in: 1000...9999))", // Unique order ID
email: "", // Optional customer email
tlfCliente: "", // Optional customer phone
datosPropietarios: "" // Optional custom data
)
return pagoDTO
}| Parameter | Type | Description |
|---|---|---|
valor | Int | Transaction amount in cents (e.g., 1550 for €15.50) |
mMoneda | Int | ISO 4217 currency code (978 = EUR, 840 = USD) |
nFactura | String | Unique order/invoice number (max 12 characters) |
email | String | Customer email for receipt (optional) |
tlfCliente | String | Customer phone number (optional) |
datosPropietarios | String | Custom merchant data (optional) |
Always convert amounts to cents to ensure precision. For €15.50, use 1550 as the valor.
Step 2: Execute the Payment
Call payWithPinpadBluetooth with the connected device, merchant data, PIN pad configuration, and payment DTO:
// Import via Bridging Header: RedsysPinpadManager.h, MerchanDTO.h
func executePayment() {
guard let config = pinpadConfig else {
print("PinPad not initialized")
return
}
// Create MerchanDTO with required fields from login response
let merchantDTO = MerchanDTO()
merchantDTO.fuc = "999008881"
merchantDTO.fucExtendido = "999008881" // Usually same as FUC
merchantDTO.terminal = "001"
merchantDTO.password = "merchant_pass" // Password from login
// Create payment DTO
let pagoDTO = createPaymentData()
// Execute payment
pinpadManager.payWithPinpadBluetooth(
selectedDevice,
merchan: merchantDTO,
config: config,
andPagoDTO: pagoDTO,
withDelegate: self
)
}When you call payWithPinpadBluetooth, the SDK:
- Prompts the customer to present their card (Insert, Swipe, or Tap)
- Reads card data via the selected method
- Requests PIN entry if required
- Encrypts card data using hardware E2EE
- Submits the authorization request to Get Mini gateway
- Returns the result via delegate callbacks
Step 3: Handle Transaction Results
The SDK delivers results through the RedsysBTPinpadPaymentDelegate callbacks.
Success Handling
func onPaymentFinished(_ result: RespuestaTransaccionDTO!, orError error: Error!) {
if let transaction = result, error == nil {
// Transaction successful - both authorized and captured
print("Sale Successful!")
print("Authorization Code: \(transaction.codigoAutorizacion ?? "N/A")")
// Save transaction details
saveTransaction(
authCode: transaction.codigoAutorizacion ?? "",
orderId: transaction.numeroOperacion ?? "",
amount: transaction.importeTotal ?? ""
)
// Check if signature is required (no-PIN transactions)
// Note: AutenticadoPorPin is a BOOL property from Objective-C
if !transaction.autenticadoPorPin {
captureCustomerSignature(for: transaction)
}
// Display success message
showSuccessAlert()
} else {
// Transaction failed
handlePaymentError(error)
}
}Progress Updates
func onPaymentProcess(_ result: Any!, orError error: Error!) {
// Called during processing for UI updates
print("Payment in progress...")
updateProgressIndicator()
}Error Handling
func handlePaymentError(_ error: Error?) {
print("Payment failed: \(error?.localizedDescription ?? "Unknown error")")
// Display user-friendly error message
showErrorAlert(message: "Transaction declined. Please try again.")
// Log error for support
logTransactionError(error)
}Key Considerations
Instant Settlement
Unlike pre-authorizations, single-step payment funds are immediately authorized and captured. These transactions settle automatically at the end of the business day without requiring a separate capture operation.
Amount Formatting
Always convert decimal amounts to cents for the PagoDTO.valor field:
| Display Amount | valor (cents) | Calculation |
|---|---|---|
| €10.50 | 1050 | 10.50 × 100 |
| €100.00 | 10000 | 100.00 × 100 |
| $25.99 | 2599 | 25.99 × 100 |
Unique Order IDs
The nFactura field must be unique for each transaction. Generate IDs using timestamps, UUIDs, or sequential numbers to prevent duplicate order tracking issues.
Signature Management
For transactions where autenticadoPorPin == false, capturing a digital signature is mandatory to meet legal requirements. The autenticadoPorPin BOOL property indicates whether PIN authentication was used. See the signature submission process in Transaction Lifecycle.
Best Practices
Prevent Duplicate Transactions
Disable payment buttons while onPaymentProcess is active to prevent multiple simultaneous payment attempts:
func executePayment() {
payButton.isEnabled = false
// Execute payment...
}
func onPaymentFinished(_ result: RespuestaTransaccionDTO!, orError error: Error!) {
payButton.isEnabled = true // Re-enable after completion
// Handle result...
}Save Transaction Data
Always save authorization codes immediately upon success. You’ll need these for refunds and reconciliation.
Provide Clear Feedback
Update your UI during onPaymentProcess to show customers that processing is occurring. Display clear success or error messages based on the final result.
Troubleshooting
Transaction Timeout
If payment times out waiting for card presentation, ensure the PIN pad is powered on and displaying the ready prompt. Check Bluetooth connection stability.
Declined Transactions
Card declines occur at the issuing bank level. Display the decline reason to customers and offer to retry with a different card or payment method.
Signature Required but Not Captured
If autenticadoPorPin == false, you must capture and submit a signature using envioFirmaDigitalizada. See Security and Licensing for details.
Next Steps
Explore additional payment features:
- Creat a Pre-authorized Payment - Reserve funds for later capture
- Transaction Lifecycle - Understand the complete payment flow
- Security and Licensing - Learn about payment security