By adding your own payment types you can handle any payment options you need. To add your own custom payment types do the following:

Step 1: Extending PaymentOption

Create a class that implements PaymentOption. Then you will need to implement it’s abstract methods. You can choose to extend the default version PaymentOption.Default() if you don’t want to override all methods but getPaymentInfoSource must be handled.

class ExamplePaymentOption implements PaymentOption {

        @Override
        public boolean handlesPaymentType(String type) {}

        @Override
        public Fragment getSelectionScreen(Merchant merchant, double amount, String currency, HashMap<String, String> extras, OnPaymentOptionSelectedListener paymentOptionSelectedListener) {}

        @Override
        public boolean presentSummaryScreen(Voucher voucher, PendingVoucher pendingVoucher, Activity activity) {}

        @Override
        public SummaryViewFactory getSummaryViewFactory() {}

        @Override
        public Fragment getClaimScreen(Voucher voucher, boolean canClaim) {}

        @Override
        public Observable<PaymentInfoSource> getPaymentInfoSource(Voucher voucher, LoadingBaseActivity activity) {}
}
class ExamplePaymentOption : PaymentOption {

    override fun summaryViewFactory: SummaryViewFactory {}

    override fun handlesPaymentType(type: String): Boolean {}

    override fun getSelectionScreen(merchant: Merchant, amount: Double, currency: String, extras: HashMap<String, String>, paymentOptionSelectedListener: OnPaymentOptionSelectedListener): Fragment {}

    override fun presentSummaryScreen(voucher: Voucher, pendingVoucher: PendingVoucher, activity: Activity): Boolean {}

    override fun getClaimScreen(voucher: Voucher, canClaim: Boolean): Fragment {}

    override fun getPaymentInfoSource(voucher: Voucher, activity: LoadingBaseActivity): Observable<PaymentInfoSource> {}
}

Overriding PaymentOption methods:

  1. handlesPaymentType(...) is responsible for determining which payment types your PaymentOption handles.

  2. getSelectionScreen(...) returns a Fragment to be shown when the user has selected your PaymentOption and the user must configure the payment before adding it to the Voucher.

  3. presentSummaryScreen(...) and getSummaryViewFactory(...) :

    presentSummaryScreen(...) determines whether you need to present a custom summary screen for your PaymentOption on checkout if you just want to use the default return false otherwise return true.

    getSummaryViewFactory(...) returns a SummaryViewFactory which is responsible for showing the subviews (header, footer, payment, price) that make up the summary screen. You can choose to override just one subview or all the subviews.

  4. getClaimScreen(...) returns a Fragment to be shown when claiming your payment after receiving a Voucher with your PaymentOption.

  5. getPaymentInfoSource(...) this method runs when needing to resolve the PaymentInfoSource inside Voucher.getPaymentInfo() before sending your Voucher. If user input is required at this state you can use the activity parameter to launch any relevant UI. Take a look at Voucher.getPaymentInfo().getError() to determine what needs to be done to resolve the payment source.

Diagnosing PaymentInfo errors

There are 4 possible errors states that you may need to handle when resolving the payment source:

  1. NONE : No Error. In this case just return the original PaymentInfoSource via Voucher.getPaymentInfo().getPaymentSourceInfo()

  2. USER_SETUP_REQUIRED : User info in the payment source hasn’t been configured, launch the needed UI to get the required info from the user

  3. VOUCHER_SETUP_REQUIRED : Voucher payment info hasn’t been configured, this may sugggest something went wrong during the setup of the voucher

  4. APPROVAL_REQUIRED : Everything is setup it just needs to be approved. In this case you can probably just return the original PaymentInfoSource inside Voucher.getPaymentInfo() as the approval will be handled by the SDK

Step 2: Add your payment option to the app

Add your new payment options to Engine during setup

Engine.Builder builder = new Engine.Builder(serverUrl, sdkId);
...
builder.addPaymentOption(new ExamplePaymentOption());
builder.build();
val builder = Engine.Builder(serverUrl, sdkId)
...
builder.addPaymentOption(ExamplePaymentOption())
builder.build()