With the Payment API, the browser native payment dialog can be used to facilitate card payments. Currently only BasicCard is supported, above that can be here can be read further. With the API the user can be queried for all his map information, this can then be checked by the server and if necessary the invalid fields can then be marked for the user.


// Creates a payment object and attaches it to our HTML document
final Payment payment = new Payment(this);

// Here we set which cards we support
// Note: Currently we only support basic-card
final List<CardNetworkIdentifier> supportedCards = Arrays.asList(, CardNetworkIdentifier.mastercard);
final List<PaymentRequestMethodData> methodData = Arrays.asList(new PaymentRequestMethodData("basic-card", new BasicCardRequest(supportedCards)));

// Next we set the items, so that the user can see, how much and for what they're paying.
final List<PaymentItem> items = Arrays.asList(
  new PaymentItem("Rubber Ducky", new PaymentAmount("EUR", "1.00")),
  new PaymentItem("Shower Head", new PaymentAmount("EUR", "5.79")),
  new PaymentItem("Toilet Paper", new PaymentAmount("EUR", "0.90")));

// Next we also add how much has to be paid in total. These numbers aren't checked, but should obviously by dynamically calculated correctly.
final PaymentItem total = new PaymentItem("Total cost", new PaymentAmount("EUR", "7.69"));

// These settings set, how the items should be sent out
final List<PaymentShippingOption> shippingOptions = Arrays.asList(
  new PaymentShippingOption("standard-shipping", "Standard Shipping", new PaymentAmount("EUR", "5.30"), true));

final PaymentRequestDetails requestDetails = new PaymentRequestDetails(total, items, shippingOptions);

// These settings set which fields need to be mandatory set and if the user can select the shipping type
final PaymentRequestOptions requestOptions = new PaymentRequestOptions()

final Consumer<PaymentResult> onResultReceived = result -> {
  // Here are the fields being validated and if everything is successfull, we can call payment.complete(Result.success)
  // If something is not valid, we can act as such:
  final PayerError payerError = new PayerError()
    .setEmail("The email is not valid!");
  final BasicCardErrors cardError = new BasicCardErrors()
    .setCardNumber("The card number is not valid!");
  final AddressErrors addressErrors = new AddressErrors(); // Nothing wrong so don't set anything

  final PaymentValidationError errors = new PaymentValidationError("Some fields are not valid!", payerError, cardError, addressErrors);
  // Instead of Lambdas, you can also pass Methods as arguments, then we'll be able to simply call these again recursively.
  payment.retry(errors, this::dummyOnSuccess, error -> {
    // If the payment should be aborted, payment.complete( can be called
    payment.complete(, (error) -> { /* Exception simply passed through or further editing */});

final Consumer<JavascriptError> onErrorReceived = error -> {
  System.err.println("An error ocurred: " + error.getMessage());

// Lastly, we only need to call the payment dialogue
payment.requestPayment(methodData, requestDetails, requestOptions, onResultReceived, onErrorReceived);