Performing a Sale¶
As noted earlier, every transaction is wrapped within a session, so all
transactions described from here forward assume that a session has been established
with a valid CommerceListener
. Multiple payments can occur within a single
session, as in the use cases for multi-tender or split-tender, but a session
should be ended before a new cart/order is started. See Getting Started
to start a session, and PSDK State Transitions for information on when different
commands can be performed.
Setup and Start a Payment¶
Before initiating a sale transaction, a Payment
object must be
established with payment type, amount, tax, etc.
1 2 3 4 5 6 7 8 9 10 11 | // A session must be open to perform a payment Payment payment = Payment.create(); // Creating a Payment also creates an empty AmountTotals object in the requested amounts. AmountTotals requestedAmounts = payment.getRequestedAmounts(); requestedAmounts.setSubtotal(ConversionUtility.parseAmount(8.00)); requestedAmounts.setTax(ConversionUtility.parseAmount(1.00)); requestedAmounts.setGratuity(ConversionUtility.parseAmount(1.00)); requestedAmounts.setTotal(ConversionUtility.parseAmount(10.00)); transactionManager.startPayment(payment); // Listener receives the PaymentCompletedEvent. |
1 2 3 4 5 6 7 8 9 10 11 12 13 | // A session must be open to perform a payment val payment = Payment.create().apply { RequestedAmounts.apply { Subtotal = Decimal(8.00) Tax = Decimal(1.00) Gratuity = Decimal(1.00) Total = Decimal(10.00) } } // Creating a Payment also creates an empty AmountTotals object in the requested amounts. transactionManager.startPayment(payment) // Listener receives the PaymentCompletedEvent. |
1 2 3 4 5 6 7 8 9 10 11 | // A session must be open to perform a payment var payment = VFIPayment.create() // Creating a Payment also creates an empty AmountTotals object in the requested amounts. var requestedAmounts = payment?.getRequestedAmounts() requestedAmounts?.setSubtotal(VFIDecimal.init(valueDecimal: Decimal.init(8.00))) requestedAmounts?.setTax(VFIDecimal.init(valueDecimal: Decimal.init(1.00))) requestedAmounts?.setGratuity(VFIDecimal.init(valueDecimal: Decimal.init(1.00))) requestedAmounts?.setTotal(VFIDecimal.init(valueDecimal: Decimal.init(10.00))) sdk.getTransactionManager()?.start(payment) // Listener receives the PaymentCompletedEvent. |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // A session must be open to perform a payment var amount_totals = new AmountTotals(); PaymentSDK.Decimal subtotal = new PaymentSDK.Decimal(8.00); PaymentSDK.Decimal gratuity = new PaymentSDK.Decimal(1.00); PaymentSDK.Decimal tax = new PaymentSDK.Decimal(1.00); PaymentSDK.Decimal total = new PaymentSDK.Decimal(10.00); amount_totals.SetWithAmounts(subtotal, tax, gratuity, total); var payment = new Payment { RequestedAmounts = amount_totals }; payment_sdk_.TransactionManager.StartPayment(payment); // Listener receives the PaymentCompletedEvent. |
// A session must be open to perform a payment
auto payment = verifone_sdk::Payment::create();
// Creating a Payment also creates an empty AmountTotals object in the requested amounts.
payment->getRequestedAmounts()->setSubTotals(8.00)
->setTax(1.00)
->setGratuity(1.00)
->setTotal(10.00);
psdk->getTransactionManager()->startPayment(payment);
// Listener receives the PaymentCompletedEvent.
.. code-tab:: c# .NET
:linenos:
// A session must be open to perform a payment
var amount_totals = AmountTotals.Create(false);
VerifoneSdk.Decimal subtotal = new VerifoneSdk.Decimal(8);
VerifoneSdk.Decimal gratuity = new VerifoneSdk.Decimal(1);
VerifoneSdk.Decimal tax = new VerifoneSdk.Decimal(1);
VerifoneSdk.Decimal total = new VerifoneSdk.Decimal(10);
amount_totals.SetWithAmounts(subtotal, tax, gratuity, total, null, null, null);
var payment = Payment.Create();
payment.RequestedAmounts = amount_totals;
payment_sdk_.TransactionManager.StartPayment(payment);
// Listener receives the PaymentCompletedEvent.
See also
Multi-Currency¶
A payment transaction can be performed with different currencies each time.
A specific currency (eg. USD, EUR) may be specified for the transaction by
configuring the currency in the transaction object
Transaction.setCurrency()
. If no currency is set, then
it defaults to the local currency. The currency which is set in the transaction
object can be overridden by settint it in the payment object
Payment.setCurrency()
.
Handling Precision of Monetary Values¶
PSDK uses the Decimal class for monetary values. The
values are represented by value and scale: please see
DecimalBase()
. A Decimal object consists of a 64 bit integer
value and a 32 bit integer scale. The scale
represents the number of digits to the right of the decimal point.
For example, 10.99 is represented as a value of 1099 and a scale of 2.
Handle Payment Completed Event¶
Once the payment has been initiated, the payment application handles everything,
including consumer UI, card reader interaction, and host authorization. We just
need to wait for the TransactionEvent.TRANSACTION_PAYMENT_COMPLETED
event and check the authorization result. The following code snippet is assumed
to be within the CommerceListener.handlePaymentCompletedEvent()
method of the instance
passed into the session. See the AuthorizationResult
enumeration for
more details on the result types.
1 2 3 4 5 6 7 8 9 10 11 12 | @Override // Overridden from the CommerceListenerAdapter public void handlePaymentCompletedEvent(PaymentCompletedEvent event) { if (TransactionEvent.TRANSACTION_PAYMENT_COMPLETED.equals(event.getType())) { if (event.getStatus() == StatusCode.SUCCESS) { Payment payment = event.getPayment(); AuthorizationResult authorizationResult = payment.getAuthResult(); // Confirm the authorization result is AUTHORIZED instead // of DECLINED or some other result. } // Else handle failure by examining the status code and message. } } |
1 2 3 4 5 6 7 8 9 10 11 12 | // Overridden from the CommerceListenerAdapter override fun handlePaymentCompletedEvent(event: PaymentCompletedEvent) { if (TransactionEvent.TRANSACTION_PAYMENT_COMPLETED.equals(event.getType())) { if (event.getStatus() == StatusCode.SUCCESS) { val payment = event.getPayment() val authorizationResult = payment.getAuthResult() // Confirm the authorization result is AUTHORIZED instead // of DECLINED or some other result. } // Else handle failure by examining the status code and message. } } |
1 2 3 4 5 6 7 8 9 10 11 12 | // Overridden from the VFICommerceListenerAdapter override func handle(_ event: VFIPaymentCompletedEvent?) { if (event?.getType() == VFITransactionEventTRANSACTIONPAYMENTCOMPLETED) { if (event?.getStatus() == VFIStatusCodeSuccess) { let payment = event?.getPayment() let authorizationResult = payment?.getAuthResult() // Confirm the authorization result is AUTHORIZED instead // of DECLINED or some other result. } // Else handle failure by examining the status code and message. } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | private void HandlePaymentCompletedEvent(PaymentCompletedEvent event) { if (event.Type.Value == TransactionEvent.TRANSACTION_PAYMENT_COMPLETED) { if (event.Status == StatusCode.SUCCESS) { Payment payment = event.Payment; AuthorizationResult authorization_result = payment.AuthResult; // Confirm the authorization result is AUTHORIZED instead // of DECLINED or some other result. } // Else handle failure by examining the status code and message. } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 | // Overridden from the CommerceListenerAdapter void handlePaymentCompletedEvent( const std::shared_ptr<verifone_sdk::PaymentCompletedEvent>& event) override { if (event->getType() == TransactionEvent::TRANSACTION_PAYMENT_COMPLETED) { if (event->getStatus() == StatusCode::SUCCESS) { auto payment = event->getPayment(); auto auth_result = payment->getAuthResult(); // Confirm the authorization result is AUTHORIZED instead // of DECLINED or some other result. } // Else handle failure by examining the status code and message. } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | private void HandlePaymentCompletedEvent(PaymentCompletedEvent sdk_event) { if (sdk_event.Type == TransactionEvent.TRANSACTION_PAYMENT_COMPLETED) { if (sdk_event.Status == 0) { var payment = sdk_event.Payment; AuthorizationResult authorization_result = payment.AuthResult.Value; // Confirm the authorization result is AUTHORIZED instead // of DECLINED or some other result. } // Else handle failure by examining the status code and message. } } |
See also
Print Receipt¶
The Receipt
can be retrieved from Payment.getReceipts()
, returning
a map of receipts, keyed by either ReceiptType.CUSTOMER
or
ReceiptType.MERCHANT
. The selected receipt can then be modified at specific
points using Receipt.insertTextAtSection(html, section)
, inserting
additional HTML into the desired section. Finally, use Receipt.getAsHtml()
to get a printable HTML string to send to the printer, or use to email/text to the
customer. See Printing for more information on the printing APIs.