Plants
& More

Redirect based Payment Methods

This example shows basic version of a payment form using redirect based Payment Methods. Redirect based payment method charge works as a payment that is confirmed by user on separate page.

Payment flow technical overview

Whole transaction consists of few simple steps:

  • Website gathers information from a customer required to initialise the payment and sends details to its backend.
  • The website's backend leverages shift4 API to create a Payment Method and a Charge using Payment Method ID.
  • Charge has initially status pending and its flow.nextAction equals redirect. Now customer has to be redirected to external page in order to finish the payment.
  • Customer is redirected to the URL specified in flow.redirect.redirectUrl property and confirms the payment.
  • After payment customer is redirect back to the page specified previously when creating the Charge request. The property clientObjectId is added as query parameter to allow payment identification.
  • Charge still has status=pending, but now its nextAction is equal to wait. We are waiting for payment result confirmation from payment method provider.
  • After few moments Charge's state is updated and gets successful or failed status.

Client object ID

Apart from regular ID every charge has clientObjectId property which holds identifier that is meant to be used with our shift4.js. Using this identifier allows our JS to get all necessary information required to finish payment, without exposing any confidential data to the customer's browser.

Simplified integration with shift4.js

Thanks to shift4.js you don't have to bother with each of required actions, as redirecting and waiting can be automatically handled for you.

To make this happen all you have to do is passing clientObjectId of created charge to the browser and call handleChargeNextAction method with it. handleChargeNextAction will automatically execute required redirect after creation the charge and afterwards await for final payment result.

To process payment to the end with this method you will need to access clientObjectId from the browser in two places:

  • After creation the Charge on your server. You can just return this identifier in the response.
  • On redirect that happened back to your site. This can be read directly from current browser location, clientObjectId will be added to the return URL as HTTP query parameter.

Showing final result

After payment process is finished handleChargeNextAction method will resolve returned promise with Charge object. It will be limited to only necessary information, with no confidential data exposed, as discussed previously.


@AjaxController
@RequestMapping("/ajax/examples/charge-with-redirecting-payment-method")
@RequiredArgsConstructor
class ExamplesAjaxChargeWithRedirectingPaymentMethodController {


    @PostMapping("/payment")
    Map ajaxPaymentMethod(@RequestBody PaymentMethodExampleRequest exampleRequest) throws IOException {
        try (Shift4Gateway shift4Gateway = createShift4GatewayForPaymentMethods()) {

            // create payment method
            var paymentMethodRequest = new PaymentMethodRequest(exampleRequest.type)
                    .billing(new BillingRequest()
                            .email(exampleRequest.email)
                            .name(exampleRequest.name)
                            .vat(exampleRequest.vat));
            var paymentMethod = shift4Gateway.createPaymentMethod(paymentMethodRequest);

            // create charge using payment method
            var chargeRequest = new ChargeRequest(100, "USD")
                    .paymentMethod(new PaymentMethodRequest(paymentMethod.getId()))
                    .flow(new ChargeFlowRequest()
                            .returnUrl(getSiteUrl() + "/examples/charge-with-redirecting-payment-method"));
            var charge = shift4Gateway.createCharge(chargeRequest);

            // pass clientObjectId of charge to frontend
            return singletonMap("clientObjectId", charge.getClientObjectId());

        } catch (Shift4Exception e) {
            throw new BadRequestException(e.getMessage());
        }
    }

    static class PaymentMethodExampleRequest {
        PaymentMethodType type;
        String name;
        String email;
        String vat;
    }
}