1. Go to this page and download the library: Download flute/sdk 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/ */
flute / sdk example snippets
lute\Sdk\Flute;
use Flute\Sdk\Models\Requests\Address;
use Flute\Sdk\Models\Requests\SaleTransactionRequest;
$flute = new Flute([
'clientId' => getenv('FLUTE_CLIENT_ID'),
'clientSecret' => getenv('FLUTE_CLIENT_SECRET'),
'environment' => 'sandbox', // or 'production'
]);
$result = $flute->transactions->saleTransaction(new SaleTransactionRequest(
amount: 10.00,
accountNumber: '4111111111111111',
currencyId: 1, // USD
expirationMonth: 12,
expirationYear: 2030,
securityCode: '123',
// Sandbox AVS denies sales without a matching billing address.
billingAddress: new Address(line1: '123 Test St', postalCode: '10001'),
/*
* Unique per order, but reuse the same value if you retry this charge.
* Duplicate control is opt-in per merchant; see the error-handling notes.
*/
referenceId: 'order-' . uniqid(),
));
echo "Transaction {$result->transactionId}: {$result->status}\n";
lute\Sdk\Flute;
// First request: acquire and store.
$flute = new Flute([
'clientId' => getenv('FLUTE_CLIENT_ID'),
'clientSecret' => getenv('FLUTE_CLIENT_SECRET'),
'environment' => 'sandbox',
]);
$token = $flute->sessions->getAccessToken();
// yourCache()->set('flute_token', $token, 3000);
// Later request: reuse the cached token — no token call is made.
$flute = new Flute([
'clientId' => getenv('FLUTE_CLIENT_ID'),
'clientSecret' => getenv('FLUTE_CLIENT_SECRET'),
'environment' => 'sandbox',
'accessToken' => $token, // from yourCache()->get('flute_token')
]);
echo $flute->sessions->getAccessToken() === $token ? "reused\n" : "reacquired\n";
lute\Sdk\Flute;
$flute = new Flute([
'clientId' => getenv('FLUTE_CLIENT_ID'),
'clientSecret' => getenv('FLUTE_CLIENT_SECRET'),
'environment' => 'sandbox',
]);
// Values from the incoming webhook HTTP request:
$rawBody = (string) file_get_contents('php://input');
$signature = $_SERVER['HTTP_FLUTE_WEBHOOK_SIGNATURE'] ?? '';
$webhookId = $_SERVER['HTTP_FLUTE_WEBHOOK_ID'] ?? '';
$timestamp = $_SERVER['HTTP_FLUTE_WEBHOOK_TIMESTAMP'] ?? '';
$secret = getenv('FLUTE_WEBHOOK_SECRET') ?: '';
// verify() throws on empty input; treat a malformed delivery as 400.
if ($signature === '' || $webhookId === '' || $timestamp === '' || $rawBody === '' || $secret === '') {
http_response_code(400);
exit;
}
/*
* verify() checks the HMAC signature AND timestamp freshness in one call, so
* replayed deliveries older than the 5-minute window are rejected by default.
* (Use the lower-level verifySignature() only if you need the HMAC check alone.)
*/
if ($flute->webhooks->verify($signature, $webhookId, $timestamp, $rawBody, $secret)) {
// Replay protection: a captured, validly-signed delivery can still be replayed
// within the freshness window. Reject IDs you have already handled — persist
// $webhookId in your own cache/DB with a TTL >= the freshness window:
// if (yourCache()->get('flute_wh_' . $webhookId)) { http_response_code(200); exit; }
// yourCache()->set('flute_wh_' . $webhookId, '1', 600);
// process the event (idempotently, keyed on $webhookId)
http_response_code(200);
} else {
http_response_code(401);
}
lute\Sdk\Flute;
use Flute\Sdk\Models\Requests\ListTransactionsRequest;
$flute = new Flute([
'clientId' => getenv('FLUTE_CLIENT_ID'),
'clientSecret' => getenv('FLUTE_CLIENT_SECRET'),
'environment' => 'sandbox',
]);
// page is zero-based: page 0 is the first (newest-first) page.
$page = $flute->transactions->listTransactions(new ListTransactionsRequest(
page: 0,
pageSize: 25,
));
echo "Total transactions: {$page->total}\n";
foreach ($page->items as $transaction) {
/*
* List rows key the identifier as "id" and get-by-id uses "transactionId";
* both are fallback-mapped, so transactionId is reliable for either shape.
*/
echo "{$transaction->transactionId} {$transaction->status}\n";
}
lute\Sdk\Flute;
use Flute\Sdk\Models\Requests\Address;
use Flute\Sdk\Models\Requests\AuthorizeTransactionRequest;
use Flute\Sdk\Models\Requests\VoidTransactionRequest;
$flute = new Flute([
'clientId' => getenv('FLUTE_CLIENT_ID'),
'clientSecret' => getenv('FLUTE_CLIENT_SECRET'),
'environment' => 'sandbox',
]);
$auth = $flute->transactions->authorizeTransaction(new AuthorizeTransactionRequest(
amount: 42.00,
accountNumber: '4111111111111111',
currencyId: 1,
expirationMonth: 12,
expirationYear: 2030,
securityCode: '123',
// Sandbox AVS denies card transactions without a matching billing address.
billingAddress: new Address(line1: '123 Test St', postalCode: '10001'),
/*
* Unique per order, but reuse the same value if you retry this charge.
* Duplicate control is opt-in per merchant; see the error-handling notes.
*/
referenceId: 'order-' . uniqid(),
));
if ($auth->transactionId === null) {
fwrite(STDERR, "Authorization did not return a transaction id (status: {$auth->status})." . PHP_EOL);
exit(1);
}
$voided = $flute->transactions->voidTransaction(new VoidTransactionRequest(
transactionId: $auth->transactionId,
));
echo "Voided {$voided->transactionId}: {$voided->status}\n";
lute\Sdk\Flute;
use Flute\Sdk\Models\Requests\RefundTransactionRequest;
$flute = new Flute([
'clientId' => getenv('FLUTE_CLIENT_ID'),
'clientSecret' => getenv('FLUTE_CLIENT_SECRET'),
'environment' => 'sandbox',
]);
$refund = $flute->transactions->refundTransaction(new RefundTransactionRequest(
transactionId: $settledTransactionId,
// amount: 10.00, // uncomment for a partial refund
));
echo "Refunded {$refund->transactionId}: {$refund->status}\n";
lute\Sdk\Enums\PaymentMethodType;
use Flute\Sdk\Flute;
use Flute\Sdk\Models\Requests\CreatePaymentSessionRequest;
$flute = new Flute([
'clientId' => getenv('FLUTE_CLIENT_ID'),
'clientSecret' => getenv('FLUTE_CLIENT_SECRET'),
'environment' => 'sandbox',
]);
$created = $flute->paymentSessions->createPaymentSession(new CreatePaymentSessionRequest(
amount: 24.99,
referenceId: 'order-1001',
returnUrl: 'https://shop.example.com/checkout/return?order=1001',
paymentMethodTypes: [PaymentMethodType::Card, PaymentMethodType::Ach],
metadata: ['orderId' => '1001'],
));
// Redirect the shopper here for hosted Checkout.
echo $created->checkoutUrl, "\n";
// On return (or from a webhook), read the session back.
$session = $flute->paymentSessions->getPaymentSession($created->id);
echo "Status: {$session->status}\n"; // Created, Cancelled, Completed, Failed
echo "Return URL: {$session->returnUrl}\n";
echo "Order: {$session->metadata['orderId']}\n";
lute\Sdk\Flute;
use Flute\Sdk\Models\Requests\CreateMerchantApiKeyRequest;
use Flute\Sdk\Models\Requests\ListMerchantsRequest;
$partner = new Flute([
'clientId' => getenv('FLUTE_PARTNER_CLIENT_ID'),
'clientSecret' => getenv('FLUTE_PARTNER_CLIENT_SECRET'),
'environment' => 'sandbox',
]);
// Find the merchant to onboard.
$found = $partner->merchants->listMerchants(new ListMerchantsRequest(search: 'cafe'));
$merchantId = (string) $found->items[0]->merchantId;
/*
* Mint the merchant's API credential. The clientSecret is returned ONLY
* here, at creation — store both values securely now.
*/
$key = $partner->merchants->createMerchantApiKey(new CreateMerchantApiKeyRequest(
merchantId: $merchantId,
tokenName: 'Cafe production key',
));
// The merchant processes payments with its own minted credential.
$merchant = new Flute([
'clientId' => (string) $key->clientId,
'clientSecret' => (string) $key->clientSecret,
'environment' => 'sandbox',
]);
// Later: audit a merchant's keys (listings never
lute\Sdk\Flute;
use Flute\Sdk\Models\Requests\ListTransactionsRequest;
use GuzzleHttp\Client;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Response;
$mock = new MockHandler([
// 1. The OAuth token response the SDK requests transparently.
new Response(200, [], (string) json_encode([
'access_token' => 'test-token',
'expires_in' => 3600,
'token_type' => 'Bearer',
])),
// 2. The API response for the first SDK call.
new Response(200, ['Content-Type' => 'application/json'], (string) json_encode([
'items' => [['transactionId' => 'tx-1', 'status' => 'Settled']],
'total' => 1,
])),
]);
$flute = new Flute([
'clientId' => 'test-id',
'clientSecret' => 'test-secret',
'environment' => 'sandbox',
'httpClient' => new Client(['handler' => HandlerStack::create($mock)]),
]);
$page = $flute->transactions->listTransactions(new ListTransactionsRequest(page: 0));
assert($page->total === 1);
assert($page->items[0]->transactionId === 'tx-1');