Getting started
please make sure that you have carefully read checkout.com api reference, and have created an account (requires 30k$ per month for income). you can easily create your sandbox account for testing.
Usage
The package implements the following endpoints:
- Customers
- Payments
- Tokens
- Instruments
//initialize checkout
final checkout = Checkout(secretKey: 'secretKey', publicKey: 'publicKey');
//create customer
Customer customer = Customer(
id: "",
email: "$randomNumber@gmail.com",
instruments: [],
name: "Saleh",
);
final customerId = await checkout.createCustomer(customer);
customer = customer.copyWith(id: customerId);
//fetch customer
customer = await checkout.getCustomerDetails(customer.email)
// both email and id can be used
//create instrument for customer
//1. create card model
final CreditCard card = CreditCard(
number: "4242424242424242",
cvv: "100",
expiryMonth: 6,
expiryYear: 2025,
last4: "4242",
scheme: "visa",
);
String token = "";
final TokenRequest tokenRequest =
TokenRequest(type: PaymentMethod.Card, card: card);
final TokenResponse tokenResponse =
await checkout.requestToken(tokenRequest);
token = tokenResponse.token;
//3. add instrument to customer
final InstrumentRequest instrumentRequest = InstrumentRequest(
type: PaymentSourceType.Token,
token: token,
customer: customer,
);
Instrument instrument = await checkout.createInstrument(
instrumentRequest: instrumentRequest);
//get instrument detials
Instrument instrument =
await checkout.getInstrumentDetails(instrument.instrumentId);
//pay with token
final PaymentRequest paymentRequest = PaymentRequest(
type: PaymentSourceType.Token,
amount: 20,
currency: "SAR",
customer: customer,
description: "participants payment",
reference: "",
);
final PaymentResponse paymentResponse =
await checkout.requestTokenPayment(
paymentRequest: paymentRequest,
//for tokenizing
card: card,
method: PaymentMethod.Card,
);
//pay with instrument id
final paymentRequest = PaymentRequest(
type: PaymentSourceType.Id,
amount: 200,
reference: "1q23",
description: "a payment",
customer: customer,
cardId: instrumentId,
currency: "SAR");
final PaymentResponse response = await checkout
.requestIdPayment(paymentRequest: paymentRequest);
Additional information
not all operations are implemeneted, for example, refunds. you can check Checkout class implementation to see what is covered.
Example with Riverpod and Flavors
//Singleton
final checkoutPvdr =
Provider((ref) => Checkout(secretKey: 'your key', publicKey: 'your key',));
enum Environment { dev, prod }
Future<void> mainCommon(Environment env) async {
WidgetsFlutterBinding.ensureInitialized();
runApp(
ProviderScope(overrides: [
if (env == Environment.dev)
checkoutPvdr.overrideWithValue(
Checkout(
secretKey: 'sanbox-key',
publicKey: 'sandbox-key',
testing: true,
),
)
], child: const Home()),
);
}
//create the customer provider
//if the customer was not register, the notifer will create a new customer
//using the email, to fetch it later with this identifier
final customerAsyncPvdr =
StateNotifierProvider<CustomerNotifier, AsyncValue<Customer>>(
(ref) => CustomerNotifier(
checkout: ref.watch(checkoutPvdr),
customerId: "e.g. firebase_auth.email",
name: "",
),
);
class Home extends ConsumerWidget {
const Home({Key? key}) : super(key: key);
@override
Widget build(context, ref) {
final watch = ref.watch;
final checkout = watch(checkoutPvdr);
final customer = watch(customerAsyncPvdr).value!;
final customerNotifier = watch(customerAsyncPvdr.notifier);
return Column(
children: [
for (final i in customer.instruments) ...[
CreditCardWidget(instrument: i),
ElevatedButton(
onPressed: () => customerNotifier.setInstrumentToDefault(i),
child: const Text("Set To Default")),
ElevatedButton(
onPressed: () => customerNotifier.updateInstrument(
instrument: i,
instrumentRequest: InstrumentRequest(
customer: customer,
expiryMonth: 7,
expiryYear: 2027,
),
),
child: const Text("Update Card")),
ElevatedButton(
onPressed: () => customerNotifier.deleteInstrument(i.id),
child: const Text("Delete Card")),
],
ElevatedButton(
onPressed: () {
customerNotifier.addInstrument(
creditCard: CreditCard(
number: "4242424242424242",
expiryMonth: 4,
expiryYear: 2027,
cvv: "100"),
);
},
child: const Text("Add Card")),
ElevatedButton(
onPressed: () => checkout.requestIdPayment(
paymentRequest: PaymentRequest(
type: PaymentSourceType.Id,
amount: 200,
reference: "1q23",
description: "a payment",
customer: customer,
cardId: customer.defaultInstrument?.id,
currency: "SAR")),
child: Text("Pay 200 With ${customer.defaultInstrument?.last4}")),
],
);
}
}
class CreditCardWidget extends StatelessWidget {
final Instrument instrument;
const CreditCardWidget({
Key? key,
required this.instrument,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
children: [
Text(instrument.last4),
const SizedBox(
height: 8,
),
Text(instrument.isDefault.toString())
],
);
}
}
Rememeber to understand the code before coping it, this is just a demo and not well orgnized and architectured! take care :)
Libraries
- checkout_api
- lib
- models/credit_card
- models/customers/customer
- models/customers/customers
- models/instruments/instrument
- models/instruments/instrument_request
- models/instruments/instruments
- models/models
- models/payment_type
- models/payments/payment_request
- models/payments/payment_response
- models/payments/payments
- models/tokens/apple_pay_token
- models/tokens/token_request
- models/tokens/token_response
- models/tokens/tokens
- notifiers/customer_notifier
- notifiers/notifiers
- providers/checkout_provider
- providers/providers
- repositories/customer_repository
- repositories/instruments_repository
- repositories/payments_repository
- repositories/repositories
- repositories/tokens_repository
- utils/api_base
- utils/api_exception
- utils/utils