1. Go to this page and download the library: Download echodial/cleat library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
echodial / cleat example snippets
use Cleat\Cleat;
$pdo = new PDO('mysql:host=127.0.0.1;dbname=app;charset=utf8mb4', 'user', 'pass');
$config =
use Cleat\Product;
use Cleat\Price;
$product = Product::create(['name' => 'Premium', 'description' => 'Everything.']);
Price::create($product, [
'lookup_key' => 'premium-monthly', // how your code refers to it
'nickname' => 'Monthly',
'amount' => 2900, // cents
'billing_type' => 'recurring',
'billing_interval' => 'month', // day | week | month | year
'interval_count' => 1,
'trial_days' => 7, // default trial for this price
]);
Price::create($product, ['lookup_key' => 'setup-fee', 'amount' => 5000]); // one-time
use Cleat\Customer;
$customer = Customer::create(['user_id' => $user->id, 'email' => $user->email, 'name' => $user->name]);
$customer = Customer::forUser($user->id);
// Guests (from payment links) have no user. Attach one to a user later, if the
// emails match and you choose to:
$customer = Customer::forUser($user->id, claimGuestWithEmail: $user->verifiedEmail);
$subscription = $customer->newSubscription('premium-monthly')
->withTrialDays(7) // overrides the price's trial_days; 0 or skipTrial() for none
->quantity(3)
->create($opaqueData); // optional: attach this card first
try {
$customer->newSubscription('premium-monthly')->create();
} catch (Cleat\Exceptions\PaymentFailedException $e) {
return redirect($e->payUrl); // the customer can pay with another card
}
$subscription->active(); // trialing or active, or past_due within grace_days
$subscription->onTrial();
$subscription->onGracePeriod(); // canceled at period end, still usable until ends_at
$subscription->pastDue();
$customer->subscribed('premium-monthly');
$subscription->cancel(); // at period end; ends_at = current_period_end
$subscription->resume(); // only before ends_at
$subscription->cancelNow(); // immediately, no refund; stops pending retries
$subscription->swap('premium-yearly'); // prorated
$subscription->swap('basic-monthly', prorate: false);
// Charge the stored card for a price, or an amount. Returns the paid invoice.
$invoice = $customer->charge('setup-fee', quantity: 2);
$invoice = $customer->invoiceFor('Rush fee', 2500);
// Build an invoice and email it. send() never charges.
$invoice = $customer->newInvoice()
->addItem('Consulting, March', 150000)
->addPrice('setup-fee', 1)
->tax(12000) // you compute tax; Cleat does not
->memo('Thanks for your business.')
->dueIn(14)
->send(); // or ->finalize() to open without emailing
$invoice->paymentUrl(); // https://billing.example.com/pay/{64 hex chars}; null once paid or void
$invoice->pay(); // charge the stored card now
$invoice->void();
$invoice->send(); // re-send; extends the hosted link
$html = $invoice->render(); // print-ready HTML (A4 or Letter)
// public/pay.php, routed from /pay/{token}
use Cleat\Http\InvoicePayPage;
session_start();
$page = new InvoicePayPage(session_id()); // Cleat binds CSRF to your session
$response = $_SERVER['REQUEST_METHOD'] === 'POST'
? $page->submit($token, $_POST, $_SERVER['REMOTE_ADDR'])
: $page->show($token);
http_response_code($response->status);
foreach ($response->headers as $name => $value) {
header("$name: $value");
}
echo $response->body;
$refund = $charge->refund(); // full
$refund = $charge->refund(2500); // partial, in cents
$refund->method; // RefundMethod::Refund, or ::Void when the charge had not settled
'automation' => [
'dunning_enabled' => true,
'retry_attempts' => [1, 3, 7], // days after the first failure
'failed_action' => 'past_due', // status while retrying
'final_action' => 'unpaid', // or 'canceled' after the last retry fails
'dispatch_emails' => true,
],
// public/webhook.php, registered in the merchant interface (Account > Webhooks)
use Cleat\Webhooks\WebhookHandler;
$response = (new WebhookHandler())->handle(file_get_contents('php://input'), getallheaders());
use Cleat\Cleat;
use Cleat\Events\PaymentFailed;
Cleat::events()->listen(PaymentFailed::class, function (PaymentFailed $e) {
// $e->invoice, $e->charge, $e->attemptNumber, $e->willRetry
});
// Bridge everything into your framework's dispatcher:
Cleat::events()->listen('*', fn (object $event) => $keelEvents->dispatch($event));
use Cleat\Mail\MailerInterface;
final class PhpMailerAdapter implements MailerInterface
{
public function __construct(private PHPMailer\PHPMailer\PHPMailer $mail) {}
public function send(string $to, string $subject, string $html, ?string $text = null): void
{
$m = clone $this->mail;
$m->addAddress($to);
$m->Subject = $subject;
$m->isHTML(true);
$m->Body = $html;
$m->AltBody = $text ?? '';
$m->send();
}
}