wayl_pay 0.2.4
wayl_pay: ^0.2.4 copied to clipboard
Typed Dart client for the Wayl merchant API.
wayl_pay #
wayl_pay is a typed Dart client for the Wayl merchant API.
It wraps the public v1 merchant endpoints exposed at https://api.thewayl.com and handles:
- API key authentication through
X-WAYL-AUTHENTICATION - Environment switching between production and staging
- Payment link creation in both
liveandtestmodes - Typed request and response models
- Pagination and status filters
- Consistent API error handling with validation details
- A raw JSON request escape hatch for forward compatibility
Covered routes #
The package currently covers all public merchant routes documented in the Wayl OpenAPI document:
GET /api/v1/verify-auth-keyGET /api/v1/channelsPOST /api/v1/linksGET /api/v1/linksGET /api/v1/links/{referenceId}POST /api/v1/links/{referenceId}/invalidatePOST /api/v1/links/{referenceId}/invalidate-if-pendingPOST /api/v1/links/batchGET /api/v1/productsGET /api/v1/products/{productId}GET /api/v1/subscriptionsGET /api/v1/subscriptions/{productId}GET /api/v1/subscribersPOST /api/v1/refundsGET /api/v1/refundsGET /api/v1/refunds/{refundId}DELETE /api/v1/refunds/{refundId}/cancel
Installation #
Add the package to your Dart or Flutter application:
dependencies:
wayl_pay: ^0.2.4
Webhook Verification #
Wayl sends payment status updates to your webhook URL. To verify the authenticity of these webhooks:
- Set a
webhookSecretwhen creating a payment link. - When your server receives a webhook, use the
WaylWebhookVerifierutility:
import 'package:wayl_pay/wayl_pay.dart';
final isValid = WaylWebhookVerifier.verify(
payload: requestBody, // raw POST body
signature: request.headers['x-wayl-signature'],
secret: 'your-webhook-secret',
);
if (!isValid) {
// Reject the webhook
}
This uses HMAC-SHA256 to verify the signature. Always check the signature before processing the webhook payload.
How it works #
wayl_pay provides a strongly-typed, modern Dart interface for the Wayl merchant API. It is designed for both Dart and Flutter projects, and abstracts away raw HTTP, authentication, and error handling.
Architecture #
- WaylPayClient: The main entry point. Configure with your API key and environment (production or staging).
- API Groups: Access endpoints via logical groups:
client.links,client.products,client.subscriptions,client.refunds, etc. - Typed Models: All requests and responses use Dart classes, so you get autocompletion and type safety.
- Error Handling: All errors throw
WaylApiException, which includes HTTP status, message, and validation errors (if any). - Extensibility: For new or undocumented endpoints, use
client.requestJsonto send custom requests and receive raw JSON.
Request Flow #
- Instantiate
WaylPayClientwith your API key:final client = WaylPayClient(apiKey: 'YOUR_KEY'); - Call an endpoint (e.g., create a payment link):
final response = await client.links.create(CreateLinkRequest(...)); print(response.data.url); - Handle errors with try/catch:
try { await client.refunds.create(...); } on WaylApiException catch (e) { print(e.message); } - Close the client when done:
client.close();
Features #
- Authentication: Uses the
X-WAYL-AUTHENTICATIONheader automatically. - Environment Switching: Use
WaylEnvironment.productionorWaylEnvironment.staging. - Pagination & Filtering: Query objects like
ListLinksQueryandListProductsQuerymake pagination and filtering easy. - Validation Errors: If the API returns validation errors, they are available in
WaylApiException.errors. - Testability: All HTTP is injectable for mocking in tests.
Example: List Pending Links #
final links = await client.links.list(
const ListLinksQuery(statuses: {LinkStatus.pending}),
);
for (final link in links.data) {
print(link.referenceId);
}
Quick start #
import 'package:wayl_pay/wayl_pay.dart';
Future<void> main() async {
final client = WaylPayClient(
apiKey: 'YOUR_WAYL_API_KEY',
environment: WaylEnvironment.production,
);
final auth = await client.authentication.verifyKey();
print(auth.message);
final links = await client.links.list(
const ListLinksQuery(take: 20, statuses: {LinkStatus.pending}),
);
for (final link in links.data) {
print('${link.referenceId}: ${link.status?.value ?? 'unknown'}');
}
client.close();
}
Creating a payment link #
final response = await client.links.create(
CreateLinkRequest(
env: LinkEnvironment.live,
referenceId: 'invoice-2026-0001',
total: 25000,
customParameter: 'customer-42',
lineItems: const [
LinkLineItem(
label: 'Premium Plan',
amount: 25000,
type: LinkLineItemType.increase,
),
],
webhookUrl: Uri.parse('https://example.com/webhooks/wayl'),
webhookSecret: 'replace-with-a-long-secret',
redirectionUrl: Uri.parse('https://example.com/payment-complete'),
),
);
print(response.data.url);
Creating a test payment link #
Use LinkEnvironment.test when you want Wayl to create a test payment link instead of a live one:
final response = await client.links.create(
CreateLinkRequest(
env: LinkEnvironment.test,
referenceId: 'invoice-test-0001',
total: 25000,
webhookUrl: Uri.parse('https://example.com/webhooks/wayl'),
webhookSecret: 'replace-with-a-long-secret',
redirectionUrl: Uri.parse('https://example.com/payment-complete'),
lineItems: const [
LinkLineItem(
label: 'Test payment',
amount: 25000,
type: LinkLineItemType.increase,
),
],
),
);
print(response.data.url);
This sends env: "test" to the Wayl API, which is useful for integration testing before switching to LinkEnvironment.live.
Wayl also requires webhookUrl, webhookSecret, and redirectionUrl when creating a link.
Error handling #
try {
await client.refunds.create(
const CreateRefundRequest(
referenceId: 'invoice-2026-0001',
reason: 'A detailed refund explanation with at least one hundred characters so it satisfies the API validation requirements.',
amount: 1000,
),
);
} on WaylApiException catch (error) {
print(error.message);
for (final validationError in error.errors) {
print('${validationError.path.join('.')}: ${validationError.message}');
}
}
Notes #
- All amounts are in IQD.
- The API uses your merchant key in the
X-WAYL-AUTHENTICATIONheader. - Use
WaylEnvironment.stagingfor test integrations if you have staging credentials. - Use
LinkEnvironment.testwhen creating links for payment-flow testing. WaylPayClient.requestJsonis available for new endpoints that may be added before this package is updated.