Payments decline. Each SDK signals it differently: the given StripeApi returns paid False for a non-positive amount, and PayPalApi returns success False. But your adapters already fold both of those into a single field. Ok, so the caller never has to learn each provider's failure dialect.
Lean on that uniformity to write a client helper that reacts to the result. process_payment charges through any processor and returns the string SUCCESS when ok is true and DECLINED otherwise. One decision branch now covers every gateway, present and future.
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):
cents = int(round(amount_dollars * 100))
resp = self._api.create_charge(cents)
return {"ok": resp["paid"], "id": resp["id"]}
class PayPalAdapter(PaymentProcessor):
def __init__(self, api):
self._api = api
def charge(self, amount_dollars):
resp = self._api.make_payment(amount_dollars)
return {"ok": resp["success"], "id": resp["txn"]}
def checkout(processor, amount):
return processor.charge(amount)
def process_payment(processor, amount):
"""Return "SUCCESS" or "DECLINED" based on the charge result."""
# TODO: charge the amount through whatever processor you were handed, then
# branch on the ok field the adapters already normalized for you: hand back
# the string SUCCESS when it is true and the string DECLINED when it is not.
# Return those strings themselves, never booleans.
pass
The editor and the test runner need a wide screen. Open this page on a desktop browser and your progress will be waiting.
Payments decline. Each SDK signals it differently: the given StripeApi returns paid False for a non-positive amount, and PayPalApi returns success False. But your adapters already fold both of those into a single field. Ok, so the caller never has to learn each provider's failure dialect.
Lean on that uniformity to write a client helper that reacts to the result. process_payment charges through any processor and returns the string SUCCESS when ok is true and DECLINED otherwise. One decision branch now covers every gateway, present and future.
Press Run Tests or ββ© to check your solution.