Single Card Payment
The following is a full example on how a card payment flow is expected to behave. For an example on other payment method different than card, on in combining several payment methods, please refer to the Multi-tender full example.
We are going to guide you on the usage of each delegate function for the Sale manager, and how they are used during a card payment. We will assume you build your Sale request with all the products, amounts, etc., and that your app UI is ready to use by, for example, a clerk.
The User Interface
From your UI, the app user will select a payment method (for example, card or cash). We will focus here in the case of Card.
After the user selects to proceed wth a card payment, your app will need to use the ePOS SDK to access the payment terminal, and then proceed to use this terminal to start the payment. If you implemented the SDK correctly, you should be subscribing (Android) or declaring the delegate methods (iOS) for such purpose. As you can see in the Object Models and samples below, actions for accepting signature, informing about progress, etc., will be called asynchronously when needed. You can run the Integration Tests provided to see it yourself on iOS and Android.
The iOS Object Model
The payment flow for purchase sales requests is largely handled by the six methods of the Sales Manager component shown below on the right side of the diagram. The completed sale is delivered in the Sale Response object:
- as a sale object if the processing was successful
- as an error object if the processing was not successful
Tip
In the provided Objective-C and Swift sample code, look first at the very bottom of the code to see the six Sales Manager methods that are used because this helps to understand the overall payment flow. Next, look at the preceding code to see the details of each method that is called in the payment flow.
The Android Object Model
The previous chapter presented the Android code for handling the various card-related events on the terminal so the sample code here has just this code, and the object model looks like this:
The Sample Code
The code demonstrates very simplistic usage of each unit of behaviour
import com.jakewharton.rxrelay2.BehaviorRelay; | |
import com.jakewharton.rxrelay2.Relay; | |
import de.wirecard.epos.util.events.Event; | |
import de.wirecard.epos.util.events.TerminalEvent; | |
import de.wirecard.epos.util.events.acceptance.AppSignatureConfirmationEvent; | |
import io.reactivex.android.schedulers.AndroidSchedulers; | |
Relay<Event> eventRelay = BehaviorRelay.create(); | |
eventRelay | |
.observeOn(AndroidSchedulers.mainThread()) | |
// Updates during the payment flow | |
.subscribe(event -> { | |
if (event instanceof TerminalEvent.SignatureRequest) { | |
// In the case when the Cardholder Signature is required by the Payment flow | |
// Your task is to respond to it by collecting the signature image from the customer and | |
// posting it back in the signatureEntered method | |
String img = "signature image in Base64 format"; | |
((TerminalEvent.SignatureRequest) event).signatureEntered(img.getBytes()); // image in base 64 | |
((TerminalEvent.SignatureRequest) event).signatureCanceled(); // sale canceled, because signature was not collected | |
} | |
else if (event instanceof TerminalEvent.SignatureConfirmation) { | |
// In the case when the Cardholder Signature was collected then the merchant is required to confirm its validity | |
// A. If the terminal has buttons that are used for Approving/Rejecting then this is either never called from Payment flow | |
// or its AppSignatureConfirmationEvent comes null | |
// B. If the terminal does not have buttons then the Application must present a user interface to Approve/Reject the Cardholder Signature | |
((TerminalEvent.SignatureConfirmation) event).getEnteredSignature(); // signature confirmation can be performed in terminal or in app | |
if (event instanceof AppSignatureConfirmationEvent) { // this event indicates it has to be confirmed in app side | |
((AppSignatureConfirmationEvent) event).signatureConfirmed(); // signature confirmed in app | |
((AppSignatureConfirmationEvent) event).signatureCanceled(); // signature confirmation canceled in app | |
} | |
} | |
else if (event instanceof TerminalEvent.PaymentInfo) { | |
// provided some information during payment which can be shown to user | |
((TerminalEvent.PaymentInfo) event).getAppLabel(); | |
((TerminalEvent.PaymentInfo) event).getApplicationId(); | |
((TerminalEvent.PaymentInfo) event).getCardholderName(); | |
((TerminalEvent.PaymentInfo) event).getPanTag(); | |
} | |
else if (event instanceof Event.Update) { | |
// update events indicates change of progress | |
((Event.Update) event).getMessage(context); | |
} | |
else if (event instanceof Event.PasswordConfirmation) { | |
//wechat payment method can ask for confirmation, that customer entered pin | |
onPasswordConfirmation((Event.PasswordConfirmation) event); | |
} | |
}); |