Your codebase wants to charge a card by calling one method: charge(amount_dollars), which returns a small uniform dict with keys ok and id. That is the target interface, PaymentProcessor.
The trouble is that real gateways do not speak this language. Stripe's SDK works in integer cents and returns paid and id. The Adapter pattern solves exactly this: wrap the incompatible provider object and translate calls back and forth, so the outside world only ever sees the clean target interface.
Both provider SDKs are given to you (StripeApi and PayPalApi). Do not change them, an adapter never edits the thing it wraps.
class StripeApi:
def create_charge(self, amount_cents):
if amount_cents <= 0:
return {"id": "ch_declined", "paid": False}
return {"id": "ch_" + str(amount_cents), "paid": True}
class PayPalApi:
def make_payment(self, dollars):
if dollars <= 0:
return {"success": False, "txn": "pp_declined"}
return {"success": True, "txn": "pp_" + str(dollars)}
class PaymentProcessor:
def charge(self, amount_dollars):
raise NotImplementedError
class StripeAdapter(PaymentProcessor):
def __init__(self, api):
self._api = api
def charge(self, amount_dollars):
"""Adapt dollars to Stripe's cents API and return {"ok", "id"}."""
# TODO: Stripe bills in whole cents, so scale the dollar amount up by a
# hundred and round it to an integer before handing it to
# self._api.create_charge. Translate the reply's paid and id fields into
# the target shape's ok and id keys, and carry no other keys across.
pass
The editor and the test runner need a wide screen. Open this page on a desktop browser and your progress will be waiting.
Your codebase wants to charge a card by calling one method: charge(amount_dollars), which returns a small uniform dict with keys ok and id. That is the target interface, PaymentProcessor.
The trouble is that real gateways do not speak this language. Stripe's SDK works in integer cents and returns paid and id. The Adapter pattern solves exactly this: wrap the incompatible provider object and translate calls back and forth, so the outside world only ever sees the clean target interface.
Both provider SDKs are given to you (StripeApi and PayPalApi). Do not change them, an adapter never edits the thing it wraps.
Press Run Tests or ββ© to check your solution.