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

# Integrate Payzah Using Direct Payment Method Links

> Skip the hosted Transit page and send customers straight to K-Net or Credit Card checkout by setting the right payment_type in your initialization request.

Direct Integration gives you precise control over which payment method your customer uses. Instead of routing through Payzah's hosted Transit Payment Page, Payzah returns a `direct_url` that sends your customer straight to the chosen payment provider — K-Net or Credit Card — without an intermediate step. Choose this integration method when you want to present payment options in your own UI and route customers based on their selection.

## When to Use Direct Integration

Use Direct Integration when:

* You have a custom-designed checkout that already shows K-Net and Credit Card as separate buttons
* You want to eliminate the intermediate Payzah-hosted page from the redirect chain
* You need independent control over which payment methods are available at specific points in your flow

<Note>
  Direct Integration does not support Apple Pay. If you need Apple Pay, use the [Transit Payment Page](/guides/transit-payment-page) with `payment_type: "3"` instead.
</Note>

## How Direct Integration Works

<Steps>
  <Step title="Choose the Correct payment_type for Your Method">
    Direct Integration uses two distinct `payment_type` values — one for K-Net and one for Credit Card. Select the value that matches the payment method your customer chose on your checkout page.

    | Payment method                  | `payment_type` value |
    | ------------------------------- | -------------------- |
    | K-Net                           | `"1"`                |
    | Credit Card (VISA / MasterCard) | `"2"`                |

    You must set this value dynamically based on your customer's selection before you send the initialization request.
  </Step>

  <Step title="Send the Initialization Request">
    From your server, send a `POST` request to the Payzah initialization endpoint with the appropriate `payment_type`. The request structure is identical to the Transit integration — only the `payment_type` value changes.

    **Endpoints**

    | Environment | URL                                                        |
    | ----------- | ---------------------------------------------------------- |
    | Test        | `https://development.payzah.net/ws/paymentgateway/index`   |
    | Production  | `https://payzah.net/production770/ws/paymentgateway/index` |

    **Headers**

    | Header          | Value                        |
    | --------------- | ---------------------------- |
    | `Content-Type`  | `application/json`           |
    | `Authorization` | `base64_encode($privateKey)` |

    <Warning>
      Your private key must never appear in client-side code, front-end JavaScript, or mobile app binaries. Always make this request from your backend server.
    </Warning>

    The tabs below show sample request bodies for each payment method:

    <Tabs>
      <Tab title="K-Net (payment_type 1)">
        <CodeGroup>
          ```json Request Body theme={null}
          {
            "trackid": "ORDER-20240927-00456",
            "amount": "11.250",
            "success_url": "https://yourstore.com/payment/success",
            "error_url": "https://yourstore.com/payment/error",
            "currency": "414",
            "language": "ENG",
            "payment_type": "1",
            "customer_name": "Fatima Al-Rashidi",
            "customer_email": "fatima@example.com",
            "customer_phone": "96598765432",
            "udf1": "order-ref-002"
          }
          ```

          ```php PHP theme={null}
          <?php

          $privateKey = 'YOUR_PRIVATE_KEY';
          $endpoint   = 'https://development.payzah.net/ws/paymentgateway/index';

          $payload = [
              'trackid'        => 'ORDER-20240927-00456',
              'amount'         => '11.250',
              'success_url'    => 'https://yourstore.com/payment/success',
              'error_url'      => 'https://yourstore.com/payment/error',
              'currency'       => '414',
              'language'       => 'ENG',
              'payment_type'   => '1',   // K-Net
              'customer_name'  => 'Fatima Al-Rashidi',
              'customer_email' => 'fatima@example.com',
              'customer_phone' => '96598765432',
              'udf1'           => 'order-ref-002',
          ];

          $ch = curl_init($endpoint);
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
          curl_setopt($ch, CURLOPT_POST, true);
          curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
          curl_setopt($ch, CURLOPT_HTTPHEADER, [
              'Content-Type: application/json',
              'Authorization: ' . base64_encode($privateKey),
          ]);

          $response = curl_exec($ch);
          curl_close($ch);

          $result = json_decode($response, true);
          ```

          ```javascript Node.js theme={null}
          const https = require('https');

          const privateKey = 'YOUR_PRIVATE_KEY';
          const payload = JSON.stringify({
            trackid:        'ORDER-20240927-00456',
            amount:         '11.250',
            success_url:    'https://yourstore.com/payment/success',
            error_url:      'https://yourstore.com/payment/error',
            currency:       '414',
            language:       'ENG',
            payment_type:   '1',   // K-Net
            customer_name:  'Fatima Al-Rashidi',
            customer_email: 'fatima@example.com',
            customer_phone: '96598765432',
            udf1:           'order-ref-002',
          });

          const options = {
            hostname: 'development.payzah.net',
            path:     '/ws/paymentgateway/index',
            method:   'POST',
            headers: {
              'Content-Type':  'application/json',
              'Authorization': Buffer.from(privateKey).toString('base64'),
            },
          };

          const req = https.request(options, (res) => {
            let data = '';
            res.on('data', (chunk) => { data += chunk; });
            res.on('end', () => {
              const result = JSON.parse(data);
              // Use result.data.direct_url to redirect the customer
            });
          });

          req.write(payload);
          req.end();
          ```
        </CodeGroup>
      </Tab>

      <Tab title="Credit Card (payment_type 2)">
        <CodeGroup>
          ```json Request Body theme={null}
          {
            "trackid": "ORDER-20240927-00789",
            "amount": "11.250",
            "success_url": "https://yourstore.com/payment/success",
            "error_url": "https://yourstore.com/payment/error",
            "currency": "414",
            "language": "ENG",
            "payment_type": "2",
            "customer_name": "Khalid Al-Mutairi",
            "customer_email": "khalid@example.com",
            "customer_phone": "96555544433",
            "udf1": "order-ref-003"
          }
          ```

          ```php PHP theme={null}
          <?php

          $privateKey = 'YOUR_PRIVATE_KEY';
          $endpoint   = 'https://development.payzah.net/ws/paymentgateway/index';

          $payload = [
              'trackid'        => 'ORDER-20240927-00789',
              'amount'         => '11.250',
              'success_url'    => 'https://yourstore.com/payment/success',
              'error_url'      => 'https://yourstore.com/payment/error',
              'currency'       => '414',
              'language'       => 'ENG',
              'payment_type'   => '2',   // Credit Card
              'customer_name'  => 'Khalid Al-Mutairi',
              'customer_email' => 'khalid@example.com',
              'customer_phone' => '96555544433',
              'udf1'           => 'order-ref-003',
          ];

          $ch = curl_init($endpoint);
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
          curl_setopt($ch, CURLOPT_POST, true);
          curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
          curl_setopt($ch, CURLOPT_HTTPHEADER, [
              'Content-Type: application/json',
              'Authorization: ' . base64_encode($privateKey),
          ]);

          $response = curl_exec($ch);
          curl_close($ch);

          $result = json_decode($response, true);
          ```

          ```javascript Node.js theme={null}
          const https = require('https');

          const privateKey = 'YOUR_PRIVATE_KEY';
          const payload = JSON.stringify({
            trackid:        'ORDER-20240927-00789',
            amount:         '11.250',
            success_url:    'https://yourstore.com/payment/success',
            error_url:      'https://yourstore.com/payment/error',
            currency:       '414',
            language:       'ENG',
            payment_type:   '2',   // Credit Card
            customer_name:  'Khalid Al-Mutairi',
            customer_email: 'khalid@example.com',
            customer_phone: '96555544433',
            udf1:           'order-ref-003',
          });

          const options = {
            hostname: 'development.payzah.net',
            path:     '/ws/paymentgateway/index',
            method:   'POST',
            headers: {
              'Content-Type':  'application/json',
              'Authorization': Buffer.from(privateKey).toString('base64'),
            },
          };

          const req = https.request(options, (res) => {
            let data = '';
            res.on('data', (chunk) => { data += chunk; });
            res.on('end', () => {
              const result = JSON.parse(data);
              // Use result.data.direct_url to redirect the customer
            });
          });

          req.write(payload);
          req.end();
          ```
        </CodeGroup>
      </Tab>
    </Tabs>
  </Step>

  <Step title="Read the direct_url from the Response">
    A successful initialization response returns `status: true` with a populated `direct_url` field. The `transit_url` field will be empty — this is the opposite of what you see with Transit Integration.

    ```json Success Response theme={null}
    {
      "status": true,
      "data": {
        "PaymentUrl": "https://development.payzah.net/pgaction",
        "PaymentID": "2019070115360420",
        "transit_url": "",
        "direct_url": "https://development.payzah.net/pgaction?PaymentID=202409271806248183"
      }
    }
    ```

    The `direct_url` already contains the `PaymentID` as a query parameter, pointing directly to the payment provider's page. Store the `PaymentID` value from `data.PaymentID` before redirecting, so you can reconcile the callback with your order.

    <Note>
      If `status` is `false`, do not redirect the customer. Display a user-friendly error, log the response details, and allow them to retry. Never redirect to a URL from a failed response.
    </Note>

    **Comparing Transit and Direct response URLs**

    | Field         | Transit (payment\_type 3) | Direct (payment\_type 1 or 2) |
    | ------------- | ------------------------- | ----------------------------- |
    | `transit_url` | Populated — redirect here | Empty                         |
    | `direct_url`  | Empty                     | Populated — redirect here     |
  </Step>

  <Step title="Redirect Your Customer to the direct_url">
    Redirect your customer's browser to the `direct_url` returned in the response. They will land directly on the K-Net or Credit Card payment provider's page.

    ```php PHP Redirect theme={null}
    <?php

    if ($result['status'] === true) {
        $directUrl = $result['data']['direct_url'];
        header('Location: ' . $directUrl);
        exit;
    }
    ```

    ```javascript Express.js Redirect theme={null}
    if (result.status === true) {
      res.redirect(result.data.direct_url);
    }
    ```

    The redirect URL follows this pattern:

    ```text theme={null}
    https://development.payzah.net/pgaction?PaymentID=2019070115360420
    ```

    <Tip>
      In production, the domain changes but the path and query string format remain the same. Always use the `direct_url` value from the response rather than constructing the URL manually.
    </Tip>
  </Step>

  <Step title="Handle the Success and Error Redirects">
    Once your customer completes or abandons payment on the provider's page, Payzah redirects them back to your `success_url` or `error_url` with the transaction result appended as query parameters.

    **Payment response fields**

    | Field                 | Description                                                        |
    | --------------------- | ------------------------------------------------------------------ |
    | `payzahReferenceCode` | Payzah's unique reference ID for this transaction                  |
    | `trackId`             | The `trackid` value you sent in the initialization request         |
    | `knetPaymentId`       | Unique ID assigned by the payment gateway (K-Net or card network)  |
    | `transactionNumber`   | Unique identifier for this specific transaction                    |
    | `trackingNumber`      | Track ID echoed back from your original request                    |
    | `paymentDate`         | Date on which the payment was processed                            |
    | `paymentStatus`       | Final outcome of the transaction (see table below)                 |
    | `udf1`–`udf5`         | Any user-defined fields you included in the initialization request |

    **`paymentStatus` values**

    | Status           | Meaning                               | Recommended action                             |
    | ---------------- | ------------------------------------- | ---------------------------------------------- |
    | `CAPTURED`       | Funds captured successfully           | Fulfil the order                               |
    | `VOIDED`         | Transaction voided before capture     | Do not fulfil; notify customer                 |
    | `NOT CAPTURED`   | Authorised but capture incomplete     | Investigate before acting                      |
    | `CANCELED`       | Customer cancelled on provider's page | Allow customer to retry                        |
    | `DENIED BY RISK` | Blocked by fraud/risk controls        | Do not fulfil; ask customer to contact support |
    | `HOST TIMEOUT`   | Gateway timed out — outcome unknown   | Hold the order and confirm status manually     |

    <Warning>
      Only fulfil an order when `paymentStatus` is `CAPTURED`. A redirect to your `success_url` without a `CAPTURED` status does not confirm that funds were collected.
    </Warning>
  </Step>
</Steps>

## Request Field Reference

Use this table when constructing your initialization request body for Direct Integration.

| Field            | Type         | Max length | Mandatory | Description                                        |
| ---------------- | ------------ | ---------- | --------- | -------------------------------------------------- |
| `trackid`        | Alphanumeric | 255        | Yes       | Unique ID per transaction — must not be reused     |
| `amount`         | Numeric      | 10         | Yes       | Transaction amount, e.g. `11.250`                  |
| `success_url`    | Alphanumeric | 255        | Yes       | Your URL for successful payment callbacks          |
| `error_url`      | Alphanumeric | 255        | Yes       | Your URL for failed or cancelled payment callbacks |
| `currency`       | Numeric      | 3          | Yes       | ISO 4217 numeric code, e.g. `414` for KWD          |
| `payment_type`   | Fixed        | 1          | No\*      | `"1"` for K-Net, `"2"` for Credit Card             |
| `language`       | Alpha        | 3          | No        | `ENG` or `ARA`                                     |
| `kfast_id`       | Numeric      | 8          | No        | K-Net faster checkout identifier                   |
| `customer_name`  | Alphanumeric | 255        | No        | Customer's full name                               |
| `customer_phone` | Alphanumeric | 255        | No        | Customer's phone number                            |
| `customer_email` | Alphanumeric | 255        | No        | Customer's email address                           |
| `udf1`–`udf5`    | Alphanumeric | 255        | No        | Additional fields for your own reference           |

<Note>
  Although `payment_type` is technically optional, you should always supply it explicitly (`"1"` for K-Net or `"2"` for Credit Card) when using Direct Integration to ensure the correct provider page is returned in `direct_url`.
</Note>
