Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

Keep checkout code independent of a payment provider by defining an application-owned payment interface and implementing it with a gateway adapter. The adapter translates your domain requests and results into the provider SDK’s types, so checkout depends on your contract—not directly on Stripe or another gateway.

Why put an adapter between checkout and a payment gateway?

If order and checkout code calls a provider SDK directly, provider-specific request objects, statuses, and exceptions can spread through the application. Changing SDK versions or adding a gateway then affects more than the integration itself.

The Adapter pattern converts an incompatible interface into one the client expects. Oracle’s Data Access Object pattern illustrates a related boundary: clients use a stable interface while implementation-specific resource access is hidden behind it. For payments, checkout calls an application-owned contract, and a gateway adapter translates that call to the provider’s API.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Define the payment contract around your product

Start with the payment operations the application actually needs. A small interface might cover creating or authorizing a payment, capturing an authorized payment, issuing a refund, and retrieving payment status. Do not add every operation a provider offers just to mirror its SDK.

public interface PaymentGateway {
    PaymentResult createPayment(CreatePayment command);
    PaymentResult capture(CapturePayment command);
    RefundResult refund(RefundPayment command);
    PaymentStatus getStatus(String paymentId);
}

CreatePayment, PaymentResult, and the other types should belong to your application, not to a provider SDK. Include the information your domain needs—such as order identity, amount, currency, and a stable operation key—without making the contract a copy of a provider request.

Model money deliberately. Stripe’s PaymentIntent creation reference requires a positive integer amount in the currency’s smallest unit and a three-letter currency code; avoid floating-point values for monetary amounts. See Stripe’s create PaymentIntent reference for the provider-specific rules.

Implement a Stripe adapter at the integration edge

A StripePaymentGateway can implement PaymentGateway. Its job is to translate the application command into Stripe SDK parameters, make the API call, and convert the response or exception into application-owned results. Keep Stripe classes and exception types inside this adapter or a similarly narrow infrastructure boundary.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
public final class StripePaymentGateway implements PaymentGateway {
    private final StripeClient stripe;

    public StripePaymentGateway(StripeClient stripe) {
        this.stripe = stripe;
    }

    @Override
    public PaymentResult createPayment(CreatePayment command) {
        // Translate command into Stripe request parameters.
        // Call Stripe and map its response into PaymentResult.
        // Map provider-specific failures into application-owned errors.
        throw new UnsupportedOperationException("Illustrative structure only");
    }
}

This is an architectural illustration, not a tested, drop-in implementation. Exact SDK calls and constructors depend on the Stripe Java SDK version you use. Stripe’s official stripe-java repository documents its client, request options, retry configuration, timeouts, supported LTS JDK versions, and version-specific migration details. The retrieved repository information listed version 34.0.0 and JDK 8, 11, 17, 21, and 25 support; those details can change, so check the repository and migration guidance for your chosen release.

Map payment outcomes as a lifecycle

A returned HTTP response does not necessarily mean an order is paid. Stripe recommends one PaymentIntent per order or customer session; a PaymentIntent may move through statuses and require customer authentication before success. Stripe documents that the resource can ultimately create at most one successful charge. See the Payment Intents API lifecycle.

Make the application’s response to each meaningful outcome explicit. Your domain status model may distinguish:

  • Pending: payment is not yet confirmed; do not mark the order paid solely because the create call returned.
  • Authentication required: the customer must complete an additional payment step.
  • Succeeded: the payment is confirmed according to the provider and your workflow.
  • Failed or canceled: the operation did not complete as intended, and checkout needs a defined recovery path.

Translate provider statuses into these domain concepts in the adapter or a dedicated mapping layer. Keep the mapping provider-aware: other gateways may have different states, events, or ways of representing authentication and final confirmation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Make retries safe with stable idempotency keys

A network timeout can leave the caller unsure whether the provider processed a request. Retrying with a new operation may create a duplicate; Stripe documents idempotency keys as a way to retry safely and return the first stored result for subsequent requests using the same key. Read Stripe’s idempotent requests reference before choosing retry behavior.

Derive the key from a stable application operation, such as a particular order’s payment creation, and reuse it when retrying that same operation. Do not generate a fresh key for every network attempt if the intent is to avoid duplicate work. Conversely, a genuinely new payment attempt should be treated as a distinct operation according to your business rules. The Stripe Java SDK documents per-request idempotency key configuration as well as retry and timeout options in its official repository.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Keep provider differences visible where they matter

An adapter reduces compile-time and conceptual coupling; it does not make gateways interchangeable. Providers can differ in authorization and capture semantics, refund behavior, supported currencies and payment methods, asynchronous notifications, and error categories. A contract that hides those differences completely can force the application into a lowest-common-denominator model or discard capabilities the product needs.

Normalize only what the application can honestly treat as common. For provider-specific capabilities that the product genuinely uses, expose a deliberate extension point or a separate provider-aware operation rather than smuggling provider SDK types into the general checkout contract. Add another adapter when there is a real second provider or migration need; the boundary is useful even with one adapter, but it does not make switching gateways effortless.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Keep payment security and compliance in scope

The Adapter pattern is an architecture boundary, not a PCI compliance shortcut. PCI Security Standards Council describes PCI DSS as applying to entities that store, process, or transmit cardholder data or sensitive authentication data, as well as entities able to affect the security of the cardholder-data environment. Whether a particular implementation is in scope depends on its actual architecture and data flows; the adapter alone does not establish scope. See the PCI DSS overview.

The Council’s Secure Software Standard addresses secure design and management of payment software, including transaction integrity and card-data confidentiality. Treat those concerns as part of the system design, not as consequences automatically delivered by a clean Java interface.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.