> ## Documentation Index
> Fetch the complete documentation index at: https://docs.i-pay.money/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a hosted payment link

> Create a payment page hosted by iMoney Encaissement and share its URL with your customer.

A payment link delegates the payment interface to iMoney Encaissement: you redirect your customer to a hosted payment page, where they choose their [payment method](https://docs.i-pay.money/en/guides/payouts-and-fees.md#fees-by-payment-method) and confirm. It is the API equivalent of the link created from the dashboard. The response returns `page_url`, the page to send to the payer (redirection, email, SMS, social network).

> [!WARNING]
>
> Never treat the customer's redirection as a payment confirmation: check the state of the link on the server side, with [Retrieve a payment link](https://docs.i-pay.money/en/api-reference/payment-by-link/retrieve-a-payment-link.md) or a [webhook](https://docs.i-pay.money/en/guides/webhooks.md), before delivering an order.

* **Authentication.** Keys and the Sandbox or Live choice follow the same rules as the rest of the API: see [Authentication](https://docs.i-pay.money/en/api-reference/authentication.md).
* **`reference`.** If you provide it rather than letting the API generate it, it becomes the identifier used to check the state of the link through [Retrieve a payment link](https://docs.i-pay.money/en/api-reference/payment-by-link/retrieve-a-payment-link.md), an unauthenticated operation. Generate a random, high-entropy value, never a sequential or predictable order identifier. Letting the API generate it avoids this risk.
* **Redirections.** Both redirect URLs must use HTTPS: an HTTP URL is rejected.
* **Expiration.** A link created through the API always expires thirty minutes after its creation, whatever value is sent in `shouldExpire`. Send the link to your customer right away, and create a new one rather than sharing an old link again.
* **Duplicates.** A second creation with the same manually provided `reference` fails validation (`422`): the reference must stay unique on your account. There is no idempotency key; no guarantee is documented for concurrent calls (to be confirmed with support). An account that is not found or inactive for the target environment returns `404`.

Common error messages: [Errors](https://docs.i-pay.money/en/api-reference/errors.md).


## OpenAPI

````yaml en/openapi.yaml POST /external_payments
openapi: 3.1.0
info:
  title: iPayMoney Merchant API
  version: 1.0.0
  description: >-
    v1 merchant contracts verified against the Rails routes, controllers and
    services. Partner contracts and non-operational v2 routes are not part of
    this public specification. Payment links must use private random references.
servers:
  - url: https://i-pay.money/api/v1
    description: Sandbox or Live depending on the headers and the key used
security: []
tags:
  - name: Payments
    description: Creation and tracking of merchant transactions
  - name: Payment links
    description: Hosted payment links
paths:
  /external_payments:
    post:
      tags:
        - Payment links
      summary: Create a hosted payment link
      parameters:
        - $ref: '#/components/parameters/TargetEnvironment'
        - name: Ipay-Payment-Type
          in: header
          required: true
          schema:
            type: string
            const: external_payment
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExternalPaymentRequest'
            examples:
              orderLink:
                summary: Payment link for an order
                value:
                  title: 'Order #1001'
                  description: 'Transaction for order #1001'
                  amount: 15000
                  on_success_redirection_url: https://your-site.com/orders/1001/success
                  on_failed_redirection_url: https://your-site.com/orders/1001/failure
      responses:
        '200':
          description: Link created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalPaymentCreateResponse'
        '404':
          description: Account not found or inactive
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          description: Invalid parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationError'
      security:
        - bearerAuth: []
components:
  parameters:
    TargetEnvironment:
      name: Ipay-Target-Environment
      in: header
      required: true
      schema:
        type: string
        enum:
          - sandbox
          - live
  schemas:
    ExternalPaymentRequest:
      type: object
      required:
        - title
      properties:
        title:
          type: string
        description:
          type: string
        amount:
          type:
            - integer
            - 'null'
          minimum: 50
        reference:
          type: string
          minLength: 32
          description: >-
            Omit for automatic generation, or provide a private random value of
            at least 128 bits.
        shouldExpire:
          type: boolean
          const: true
          default: true
          description: The current v1 always creates an expiring link.
        on_success_redirection_url:
          type: string
          format: uri
          pattern: ^https://
        on_failed_redirection_url:
          type: string
          format: uri
          pattern: ^https://
    ExternalPaymentCreateResponse:
      type: object
      properties:
        title:
          type: string
        amount:
          type:
            - integer
            - 'null'
        reference:
          type: string
        status:
          type: string
          example: initiated
        should_expire:
          type: boolean
        page_url:
          type: string
          format: uri
    Error:
      type: object
      properties:
        message:
          type: string
        status:
          type: string
          description: >-
            Only present on some application failures, e.g. a duplicate payment
            on `POST /payments`, where `status` is always `failed`. Absent from
            the other errors of this contract (e.g. 404 `Payment Not Found`,
            header/authentication errors).
          x-verified: >-
            Internal verification note (not intended for the public
            documentation). See `Live::PaymentService#error_response`
            (app/services/live/payment_service.rb:994-1005).
          example: failed
    ValidationError:
      type: object
      properties:
        errors:
          type: array
          items:
            type: string
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: Secret key of the Sandbox or Live account

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.