Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Conekta Php Laravel Package

conekta/conekta-php

Official PHP SDK for Conekta payments (requires PHP 8.1+). Install via Composer, authenticate with a bearer token, and call generated API clients for charges, customers, orders, and antifraud rules.

View on GitHub
Deep Wiki
Context7

Getting Started

1. Install and pin the version. The README tells you to add a VCS repository and require *@dev, which is a red flag for production. Prefer the Packagist release if one satisfies your constraint, otherwise use the VCS repo but pin a tag:

{
  "repositories": [{ "type": "vcs", "url": "https://github.com/conekta/conekta-php.git" }],
  "require": { "conekta/conekta-php": "^5.0" }
}

Never ship *@dev — you will silently pull breaking changes from master on every composer update. Check composer show conekta/conekta-php after install to confirm what you actually got.

2. Confirm your runtime. Minimum is PHP 8.1. This is the first thing to verify in an existing Laravel app; if you are on 8.0 or older, either upgrade the runtime or plan on the legacy SDK. Also check your guzzlehttp/guzzle constraint resolves — the SDK brings its own dependency and conflicts here surface as cryptic Composer errors.

3. Authenticate once, deliberately. The README's quickstart uses the global default configuration:

$config = Conekta\Configuration::getDefaultConfiguration()
    ->setAccessToken(config('services.conekta.key'));

Put the key in config/services.php + .env (CONEKTA_KEY), never in code. Separate keys per environment, and keep the sandbox key out of production config.

4. Where to look first. This is an OpenAPI-generated SDK, so there is no hand-written façade to learn. Read in this order:

  • src/Api/*Api.php — the actual endpoints (OrdersApi, CustomersApi, PaymentMethodsApi, WebhooksApi, AntifraudApi, …). Each method is one HTTP call.
  • src/Model/*.php — the request/response schemas. These mirror the Conekta OpenAPI spec; the property names are your source of truth for payload shape.
  • src/Configuration.php — host, access token, and the per-client knobs you will actually touch.
  • The conekta/openapi repo linked in the README — better prose docs than the generated PHP docblocks.

5. First real use case. Don't start with charges. Start with the smallest read call that proves auth works, then build the order flow:

$orders = new Conekta\Api\OrdersApi(new GuzzleHttp\Client(), $config);

$order = $orders->createOrder(
    new Conekta\Model\OrderRequest([...]), // line items, customer info, currency MXN
    acceptLanguage: 'es'
);

header('Location: ' . $order->getCheckout()->getUrl());

The typical day-one path is: create customer → create order with line items → attach a payment method (card token from Conekta.js, or SPEI/oxxo for cash) → redirect or render the payment instructions → reconcile via webhook.

Implementation Patterns

Wrap the generated API in your own service class. The SDK gives you ~20 API classes and hundreds of models; your app should expose maybe five methods. This is the single highest-value pattern because it isolates you from regeneration churn:

final class ConektaGateway
{
    public function __construct(private Conekta\Configuration $config) {}

    public function createOrder(OrderData $data): Conekta\Model\OrderResponse
    {
        return (new Conekta\Api\OrdersApi($this->client(), $this->config))
            ->createOrder($this->toRequest($data), acceptLanguage: 'es');
    }
}

Bind it in a service provider. Nothing else in the codebase should new Conekta\Api\....

Configure the Guzzle client explicitly. The default new GuzzleHttp\Client() has no timeout, and a hung Conekta call will hang a PHP-FPM worker or a queue job forever:

$client = new GuzzleHttp\Client([
    'timeout' => 10,
    'connect_timeout' => 3,
]);

Pass that client into every API instance. Since the SDK accepts ClientInterface, you can also attach middleware here — HandlerStack with a logging middleware in local env, or a retry middleware for GETs only (see gotchas).

Use one Configuration per tenant/credential, not the global default. Build it from config and inject it:

$config = (new Conekta\Configuration())
    ->setAccessToken($tenant->conekta_key)
    ->setHost(config('services.conekta.host'));

This is what makes the package testable and multi-tenant-safe. Reserve getDefaultConfiguration() for throwaway scripts.

Test with Guzzle's MockHandler. Because the client is injected, you can exercise your gateway without touching the network:

$mock = new GuzzleHttp\Handler\MockHandler([
    new GuzzleHttp\Psr7\Response(200, [], json_encode($fixture)),
]);
$client = new GuzzleHttp\Client(['handler' => GuzzleHttp\HandlerStack::create($mock)]);

Record real sandbox responses as fixtures once, then assert your gateway maps them to your own DTOs. This turns a 91-star, zero-dependent SDK into something you can refactor safely.

Keep a transformer layer between Eloquent and SDK models. Conekta\Model\OrderRequest wants its own shape. Write explicit toRequest() / fromResponse() functions rather than spreading model construction across controllers. When the generated model changes, one file changes.

Push all writes to queued jobs. Order creation, refunds, and customer updates are network-bound and can 5xx. Dispatch a job with $tries = 3 and exponential backoff, and persist the local record before the call with a pending status so you can reconcile.

Build the webhook receiver as the source of truth. Treat API responses as optimistic and webhook events as authoritative for payment state. The pattern that holds up:

  1. Verify the signature (Conekta signs the raw body with your public key — see the webhook docs; do not trust $_POST after framework middleware has mutated the payload).
  2. Persist the raw event with a unique constraint on the event ID.
  3. Return 200 immediately.
  4. Queue the handler; it must be idempotent because events can be delivered more than once and out of order.

Centralize error translation. Catch the SDK's API exception type at the gateway boundary and map it to your own domain exceptions (PaymentDeclined, ConektaUnavailable). Inspect the exception's code, response body, and headers once — Conekta returns structured failure details there — and log them. Controllers should never catch Conekta\* classes.

Gotchas and Tips

The static default configuration is a footgun. Configuration::getDefaultConfiguration() is process-global. Under Octane, or in a queue worker that processes multiple tenants, a key set by one request leaks into the next. Build configurations explicitly and inject them; if you must use the default, reset it in a middleware terminate().

*@dev in the README's install block will bite you. The README is generated and points at master. Combined with a generated-SDK release cadence, a composer update can change method signatures and model properties in what looks like a minor bump. Pin a tag, commit the lockfile, and read the diff before upgrading — generated changelogs are often just commit lists.

Named arguments are your friend. Generated methods take request models plus positional scalars like $accept_language and $x_child_company_id. Positional calls are easy to transpose and fail confusingly (a wrong Accept-Language changes the language of the error message you are trying to parse). Pass acceptLanguage: 'es' consistently in production so your error-message logging is in one language.

Amounts are integers in the smallest currency unit. 100.00 MXN is 10000. Mixing floats in is the classic source of rounding bugs in Mexican payment integrations. Store cents in the DB and never convert until display.

Do not retry POSTs blindly. A retried createOrder or refund can double-charge. Only add retry middleware to idempotent GETs, or use Conekta's idempotency header (exposed as a header parameter on relevant methods) and key it off your own order UUID. Without that, a timeout on a POST is ambiguous — reconcile by querying the order before retrying manually.

Never send raw card data through your server. Card numbers must be tokenized client-side with Conekta.js and only the token submitted. This keeps you out of PCI scope and is non-negotiable regardless of what the SDK technically accepts.

Don't hand-set the Accept header. Conekta pins the API version via a vendor media type in Accept. The SDK sets it for you; overriding it to application/json gets you either an error or an unpinned version with a different response shape. Same for the base host — use setHost() for sandbox rather than string-splicing URLs.

Webhook signature verification has ordering hazards. Laravel's VerifyCsrfToken and any body-parsing middleware can interfere. Exclude the webhook route from CSRF, read $request->getContent() (raw body) before any decoding, and verify against that exact byte string. A signature check that passes in a unit test but fails in production is almost always a body-mutation issue.

There is no Laravel wrapper, no facade, no events, no config publishing. 91 stars and zero dependents means you will not find Stack Overflow answers for this SDK — you will read src/Api/*.php. Budget the first integration as a genuine read-the-source task, and keep your gateway thin so the next person can do the same.

Logging is a compliance hazard. Turning on Guzzle debug => true dumps full request/response bodies including tokens, customer PII, and payment details into laravel.log. Gate it behind APP_DEBUG and a local-only check, and scrub headers in any custom logging middleware.

Extension points are limited to the transport layer. There are no model hooks or observer classes. Your leverage is: custom GuzzleHttp\Client + HandlerStack middleware (logging, retries, correlation IDs), a wrapper service, and your own DTOs. That is enough — but it means every cross-cutting concern lives in your code, not the package's.

Watch the release cadence. Recent releases plus generated code means breaking changes can arrive without a major version bump. Add a smoke test in CI that hits the sandbox with a cheap read call once per deploy; it catches credential rotation and silent schema drift faster than reading release notes.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log