# Basic Integration Flow: Hello World With a Full Working Charge

This page describes the easiest way of integrating your merchant website with Hyp CreditGuard, covering both the user and developer perspectives. It consists of the following steps:

1. The user clicks a checkout link on the merchant website.
2. The merchant website makes an API call to Hyp CreditGuard requesting a payment page to be generated.
3. Once it receives a payment page URL, the merchant website redirects the user to the payment page. The merchant website also passes URLs to open in case of successful payment or payment error.
4. The user enters their credit card details and clicks the **Pay** button.
5. Hyp CreditGuard performs the transaction, determines its status, and redirects the user to one of the URLs provided by the merchant website depending on the status of the transaction.
6. (Optional) The merchant website checks the validity of the transaction.

After reading this page, you will understand how to set up a simple payment flow to charge a credit card using the Hyp CreditGuard API. This flow is also described in [Integrating Hyp’s Payment Page and Accepting Payment](/enterprise/payment-page-integration/integrating-hyps-payment-page-and-accepting-payment.md) in a more general way, without focusing on implementation details.

Code samples on this page are written in JavaScript, and assume the use of Express.js on the backend and vanilla JavaScript/HTML on the frontend. If you're using a different tech stack, you may need to change the frontend and backend code, but the principles of interacting with the Hyp CreditGuard API will remain the same.

## Prerequisites

This page assumes that you have completed all the [prerequisites and requirements](/enterprise/introduction/prerequisites-and-requirements.md) for making Hyp CreditGuard API calls, such as obtaining a username, password, merchant ID, and terminal number.

## Step 1. Request a payment page from your checkout page

The most common way of requesting a payment page is from a checkout page on your merchant website. When visiting this page, the user has already selected products that they want to buy, added them to their shopping cart, specified shipping details, and entered any coupon codes that may have influenced the pricing of the selected products. Viewing the checkout page is the last chance for the user to review products to buy before proceeding to pay for them.

![Shopping cart items](/files/LtZrpZgEsbBZCQMwQmcn)

On this page, the user is now ready to proceed to payment when they click the **Checkout** button.

As a developer integrating with Hyp CreditGuard, you want to add a handler to the **Checkout** button that requests a basic credit card payment page from Hyp CreditGuard.

Let's assume that your checkout page has the following **Checkout** button:

```html
<button id="checkout-button">Checkout</button>
```

When the user clicks the button, your handler on the frontend may be similar to this:

```javascript
    document.getElementById("checkout-button").addEventListener("click", async () => {
        try {
            const response = await fetch("/checkout", {
                method: "POST",
                headers: { "Content-Type": "application/json" }
            });
            const data = await response.json();
            if (data.paymentUrl) {
                window.location.href = data.paymentUrl;
            } else {
                alert("Error processing payment");
            }
        } catch (error) {
            console.error("Error during checkout:", error);
        }
    });

```

This handler makes a call to your backend's `/checkout` endpoint, and that's where the first call to the Hyp CreditGuard API happens:

```javascript
app.post("/checkout", async (req, res) => {
  if (cart.length === 0) {
    return res.status(400).json({ error: "Cart is empty" });
  }

  const uniqueId = uuidv4();
  const successUrl = `${publicUrl}/success.html`;
  const errorUrl = `${publicUrl}/error.html`;

  const totalAmount = cart.reduce((sum, item) => sum + item.price, 0);

  const xmlPayload = `<?xml version="1.0" encoding="UTF-8"?>
  <ashrait>
      <request>
          <version>2000</version>
          <language>ENG</language>
          <command>doDeal</command>
          <doDeal>
              <terminalNumber>${credentials.terminal}</terminalNumber>
              <cardNo>CGMPI</cardNo>
              <total>${totalAmount}</total>
              <transactionType>Debit</transactionType>
              <creditType>RegularCredit</creditType>
              <currency>ILS</currency>
              <transactionCode>Internet</transactionCode>
              <validation>TxnSetup</validation>
              <mid>${credentials.mpi_mid}</mid>
              <uniqueid>${uniqueId}</uniqueid>
              <mpiValidation>AutoComm</mpiValidation>
              <successUrl>${successUrl}</successUrl>
              <errorUrl>${errorUrl}</errorUrl>
          </doDeal>
      </request>
  </ashrait>`;

  try {
    const response = await axios.post("https://your-hyp-environment-url/xpo/Relay", null, {
      params: {
        user: credentials.user,
        password: credentials.password,
        int_in: xmlPayload
      },
      headers: { "Content-Type": "application/x-www-form-urlencoded" }
    });

    xml2js.parseString(response.data, (err, result) => {
      if (err) {
        console.error("Error parsing XML response:", err);
        return res.status(500).json({ error: "Error processing payment response" });
      }

      const paymentUrl = result?.ashrait?.response?.[0]?.doDeal?.[0]?.mpiHostedPageUrl?.[0]?.trim();
      if (paymentUrl) {
        res.json({ paymentUrl });
      } else {
        res.status(500).json({ error: "Payment URL not found in response"});
      }
    });
  } catch (error) {
    console.error("Error processing payment:", error);
    res.status(500).json({ error: "Payment processing failed" });
  }
})
```

Here's a summary of what happens in this endpoint:

1. You send a `POST` request to the Hyp CreditGuard API endpoint `https://your-hyp-environment-url/xpo/Relay`, passing your merchant credentials and transaction details in XML format, wrapped in a parameter called `int_in`. Make sure to use the base URL provided to you by Hyp instead of `your-hyp-environment-url`.
2. You parse the response looking for the payment page URL that Hyp CreditGuard has generated for you. This URL is provided in the `mpiHostedPageUrl` element.
3. If the payment page URL is found, you return it for your frontend to use; otherwise, you return an error.

Most of the XML elements that you include in your request's `int_in` parameter in this basic scenario should be used exactly as in the code sample above. Here's a list of variable elements:

* `terminalNumber`: a unique number assigned to you as a merchant during [registration](/enterprise/introduction/prerequisites-and-requirements.md).
* `language`: defines the UI language of the requested payment page and the language of text values in the XML response. Use `HEB` for Hebrew or `ENG` for English. Other language codes are not supported and will fall back to English. Note that there's an alternative method of setting the UI language of the payment page - see [Changing the UI Language](/enterprise/changing-the-default-payment-page-appearance/changing-the-ui-language.md) for details.
* `total`: the total payment due in currency subunits, such as cents or agorot. For example, if the total in the user's payment cart is $47.30, the number that you pass in the `total` element should be 4730.
* `currency`: the currency code according to [ISO-4217](https://en.wikipedia.org/wiki/ISO_4217). For example, *ILS* for Israeli new shekels, *USD* for US dollars, etc.
* `mid`: merchant ID assigned to you as a merchant during [registration](/enterprise/introduction/prerequisites-and-requirements.md).
* `uniqueid`: a string ID of up to 64 characters that you generate for each transaction and that should be unique for at least the last 24 hours. In the code sample above, it is generated with the [uuid package](https://www.npmjs.com/package/uuid) that implements the [RFC 9562](https://www.rfc-editor.org/rfc/rfc9562.html) standard.
* `successUrl`: the URL on the merchant website that Hyp CreditGuard should redirect to upon successful payment.
* `errorUrl`: the URL on the merchant website that Hyp CreditGuard should redirect to in case of a payment error.

## Step 2. Redirect the user to the payment page

A typical successful response to the request sent in step 1 looks like this:

```xml
<?xml version='1.0'?>
<ashrait>
    <response>
        <command>doDeal</command>
        <dateTime>2025-04-07 12:49</dateTime>
        <requestId/>
        <tranId>115604795</tranId>
        <result>000</result>
        <message>Permitted transaction</message>
        <userMessage>Permitted transaction</userMessage>
        <additionalInfo/>
        <version>2000</version>
        <language>Eng</language>
        <doDeal>
            <status>000</status>
            <statusText>Permitted transaction</statusText>
            <extendedStatus/>
            <extendedStatusText/>
            <extendedUserMessage/>
            <terminalNumber>0882800016</terminalNumber>
            <cardBin>CG</cardBin>
            <cardMask>CGGMPI</cardMask>
            <cardLength>5</cardLength>
            <cardNo>xGMPI</cardNo>
            <cardName/>
            <cardExpiration/>
            <cardType code=""/>
            <extendedCardType code="0">Credit</extendedCardType>
            <blockedCard/>
            <lifeStyle/>
            <customCardType/>
            <creditCompany code=""/>
            <cardBrand code=""/>
            <cardAcquirer code=""/>
            <serviceCode/>
            <transactionType code="01">RegularDebit</transactionType>
            <creditType code="1">RegularCredit</creditType>
            <currency code="1">ILS</currency>
            <baseCurrency/>
            <baseAmount/>
            <transactionCode code="52">Internet</transactionCode>
            <total>1000</total>
            <firstPayment/>
            <periodicalPayment/>
            <numberOfPayments/>
            <paymentsInterest/>
            <mid>11665</mid>
            <uniqueid>0.5097468543670822</uniqueid>
            <mpiValidation>AutoComm</mpiValidation>
            <token>2350cd45-430a-43ca-b18f-7c54043fdbc8</token>
            <mpiHostedPageUrl>
                https://cgmpiuat.creditguard.co.il:443/CGMPI_Server/PerformTransaction?txId=2350cd45-430a-43ca-b18f-7c54043fdbc8
            </mpiHostedPageUrl>
            <returnUrl/>
            <successUrl/>
            <errorUrl/>
            <cancelUrl/>
            <clubId/>
            <validation code="106">TxnSetup</validation>
            <idStatus code=""/>
            <cvvStatus code=""/>
            <authSource code="6">MPIServer</authSource>
            <authNumber/>
            <fileNumber/>
            <slaveTerminalNumber/>
            <slaveTerminalSequence/>
            <eci/>
            <clientIp/>
            <email/>
            <cavv code=""/>
            <user/>
            <addonData/>
            <supplierNumber/>
            <id/>
            <shiftId1/>
            <shiftId2/>
            <shiftId3/>
            <shiftTxnDate/>
            <cgUid>115604795</cgUid>
            <cardHash/>
            <ashraitEmvData>
                <mti>100</mti>
            </ashraitEmvData>
            <extendedTranCode/>
            <sendNotification/>
            <sessionCD/>
        </doDeal>
    </response>
</ashrait>
```

As long as the value of `result` is `000`, signifying a green light to perform the transaction, you're only interested in the payment page URL, which is found in the `mpiHostedPageUrl` element:

```xml
<?xml version='1.0'?>
<ashrait>
    <response>
        ...
        <doDeal>
            ...
            <mpiHostedPageUrl>
                https://cgmpiuat.creditguard.co.il:443/CGMPI_Server/PerformTransaction?txId=2350cd45-430a-43ca-b18f-7c54043fdbc8
            </mpiHostedPageUrl>
            ...
        </doDeal>
    </response>
</ashrait>
```

You need to read this value and return it to your frontend. When the frontend receives the URL, it can redirect the user to the payment page:

```javascript
const data = await response.json();
if (data.paymentUrl) {
    window.location.href = data.paymentUrl;
}
```

## Step 3. Wait for the user to enter payment details on the payment page

When redirected, the user finds themself on the landing page hosted by Hyp CreditGuard. If you've set `language` to `ENG` in your request, the payment page looks like this:

![Payment page](/files/blbEqKpUoZcW6CgMjJ5M)

The user can now enter their payment details securely, without exposing them to your website, thereby freeing you as a merchant from many PCI DSS requirements.

{% hint style="info" %}
Note that in this basic scenario, the payment UI opens on the Hyp CreditGuard domain as an independent page, using the default UI design. In more advanced integration scenarios, you can:

1. Load the payment page [in an iframe](/enterprise/payment-page-integration/full-page-redirect-vs-iframe-based-integration.md) within a page on your own domain.
2. Provide [custom CSS and text](/enterprise/changing-the-default-payment-page-appearance/overview.md) to align the payment UI with your merchant website's design specifications.
   {% endhint %}

After entering payment card details, the user can click the **Pay** button. Hyp CreditGuard then processes the payment card details. Upon completion, Hyp CreditGuard redirects the user to the success or error page on your merchant website that you've specified in your original payment page request.

If the user was redirected to the success page, you may want to perform an additional step: validate the transaction.

## Step 4. Validate the transaction

Once the user has been redirected to the success page, the transaction is technically complete. However, some merchants may want to validate the transaction for regulatory or security policy reasons.

You can validate the transaction in one of two ways:

1. Send an additional request to Hyp CreditGuard providing the transaction ID and receive a response confirming the outcome of that transaction.
2. Compare the MAC (message authentication code) received from Hyp CreditGuard with the MAC that you calculate yourself.

For details on both of these methods, see [Transaction Validation](/enterprise/advanced-security-guidelines/transaction-validation.md).

The MAC validation method is faster since it allows you to skip making another API call. Let's see how to use it.

When redirecting to your success or error page, Hyp CreditGuard passes a query string with several parameters. Below is a sample success page URL with its query parameters:

```
https://your-merchant-website/success.html?uniqueID=5c8cf9b0-1be1-4cdc-857e-3b3b102b19aa&lang=EN&authNumber=&cgUid=115607512&responseMac=6741715227eb0f60e14c6da7e26d1edbd0139784b8be94b664b6aba7b5f99380&cardToken=1092880571131111&cardExp=0731&personalId=&cardMask=411111******1111&txId=d08ba620-df0d-4b3b-8be0-c0e3e6f603f2&numberOfPayments=0&firstPayment=&periodicalPayment=
```

One of the parameters, `responseMac`, is the MAC calculated by Hyp CreditGuard. You must use several of the other parameters and your merchant password to calculate MAC on your end, and then compare it to `responseMac`. If they're identical, it means that the transaction is valid.

First, concatenate the following values in this exact order:

1. Your merchant password.
2. `txId` (transaction ID) from the query string.
3. `errorCode` (if received; `000` otherwise).
4. `cardToken` (if received; an empty string otherwise).
5. `cardExp` (if received; an empty string otherwise).
6. `personalId` (if received; an empty string otherwise).
7. `uniqueId` (your unique merchant ID).

If any parameters are empty, use an empty string instead. One notable exception is `errorCode`: if it's empty, use the value `000` instead.

Hash the resulting string using SHA-256, transform it to base64, and compare the resulting value with `responseMac`.

Let's see how this can be implemented in the sample Express.js application.

On the frontend, your success page may look like this:

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Payment Successful</title>
</head>
<body>
    <h1>Payment Successful</h1>
    <p>Thank you for your purchase! Your payment was successful.</p>
    <a href="/">Return to Store</a>
</body>
</html>

<script>
  const params = new URLSearchParams(window.location.search);

  fetch(`/validate-mac?${params.toString()}`)
    .then(res => res.json())
    .then(data => {
        document.body.innerHTML += data.valid ?
            "<p>Transaction verified successfully ✅</p>" :
            "<p>MAC validation failed ❌</p>";
    });
</script>

```

It makes a call to the `validate-mac` endpoint on your backend, passing the query string. When the response arrives, it displays the transaction verification status to the user accordingly.

The `validate-mac` endpoint on the backend is as follows:

```javascript
app.get("/validate-mac", (req, res) => {
  const {
    txId,
    errorCode,
    cardToken,
    cardExp,
    personalId,
    uniqueID,
    responseMac
  } = req.query;

  const baseString = [
    credentials.password,
    txId ?? "",
    errorCode ?? "000",
    cardToken ?? "",
    cardExp ?? "",
    personalId ?? "",
    uniqueID ?? ""
  ].join("");

  const calculatedMac = crypto.createHash("sha256").update(baseString).digest("hex");

  res.json({ valid: calculatedMac === responseMac })
});
```

Here's what happens in this code snippet:

1. All parameters required for MAC calculation and comparison are extracted from the query string passed from the frontend.
2. The merchant password and the parameters used in MAC calculation are saved in a specific order to an array, which is then converted to a string.
3. The `crypto` Node module hashes the resulting "base" string using SHA-256 and outputs it as a hexadecimal string. The result is stored in the `calculatedMac` variable.
4. The endpoint returns `{valid: true}` if the calculated MAC matches the MAC received from Hyp CreditGuard, and `{valid: false}` otherwise.

## Common pitfalls and troubleshooting

### Invalid API credentials

Ensure that your API credentials (username, password, terminal number, merchant ID) are correct and match the environment (test or production). Ensure you store them securely using a secret manager or environment variables, and only use them on the backend of your application.

### Wrong total amount

Note that Hyp CreditGuard expects the total amount as a string representing the number of cents, agorot, or equivalent currency subunits. If you store prices differently, such as in fixed-point decimals, make sure to perform the necessary conversions before passing the total due to Hyp CreditGuard.

### MAC calculation pitfalls

Make sure to provide default values for the parameters used in calculating MAC on your backend. If a parameter is not provided in the query string received from Hyp CreditGuard, explicitly replace it with an empty string to avoid concatenating unexpected values such as `null` and `undefined`. For the errorCode parameter, remember that instead of an empty string, it should be replaced with `000` if empty.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://developers.hyp.co.il/enterprise/introduction/basic-integration-flow-hello-world-with-a-full-working-charge.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
