> ## Documentation Index
> Fetch the complete documentation index at: https://nayax-44d6e37b-docs-marshall-faq-redistribution.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Vending Events

Vending events are a crucial aspect of the Marshall SDK, enabling your application to handle various stages of the vending process.

* For **Java** and the **C#** SDKs the `vend_callbacks_t` interface defines the set of callback methods that your application must implement to respond to these events.
* In the **C** SDK the `vmc_vend_event_e` enumeration performs the same.

The sections below provide an overview of these events and their respective callback methods.

## Vending Callbacks Interface

<Warning>
  **Java and C# SDKs Only**

  The interface described on this section is relevant for the **Java** and **C#** SDKs only.
</Warning>

The `vend_callbacks_t` interface is designed to handle events related to vending operations.

<CodeGroup>
  ```java Java theme={null}
  public abstract static interface vend_callbacks_t
  ```

  ```csharp C# theme={null}
  public abstract static interface vend_callbacks_t
  ```
</CodeGroup>

Implementing this interface allows your application to manage the lifecycle of a vending session, from initiation to settlement, and handle various statuses and commands received from Nayax's devices. Below is a list of methods available when using the `vend_callbacks_t` interface:

### Interface Methods

The table below provides a more detailed description of the Methods.

| Method                                                         | Description                                                                                                                                                                                                           |
| :------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `onReady(vmc_link.vpos_config_t config)`                       | This method is called when the link with the VPOS (Vend Point of Sale) is successfully established and the device is ready for vending operations. It provides the configuration details of the VPOS.                 |
| `onSessionBegin(int funds_avail)`                              | Triggered when a client presents a credit card, indicating that a new session has begun and funds are available for the transaction.                                                                                  |
| `onTransactionInfo(vend_session_data_t data)`                  | Called on receipt of transaction data, providing detailed information about the current transaction.                                                                                                                  |
| `onVendApproved(vend_session_t session)`                       | Invoked when a vending request is approved. This method should return `true` if the vendor process was successful, indicating that the client’s credit card will be charged, or `false` if the vendor process failed. |
| `onVendDenied(vend_session_t session)`                         | Called when a vending request is denied, allowing the application to handle the denial accordingly.                                                                                                                   |
| `onSettlement(boolean success)`                                | Triggered when a transaction settlement occurs, indicating whether the settlement was successful.                                                                                                                     |
| `onStatus(int status)`                                         | Called when the peripheral receives a `Status` command from Nayax's device, providing the current status of the session as defined in the Marshall Protocol section 8.11.                                             |
| `onOpenedSessions(ushort[] sessions)`                          | This is invoked when the peripheral receives a `Get Session Status` command from Nayax's device. It helps identify which sessions are open, especially in multi-session mode. (See Marshall Protocol section 8.27.5)  |
| `onReaderState(boolean enabled)`                               | Provides the status of the reader, indicating whether it is enabled or disabled. (See Marshall Protocol section 8.27.9)                                                                                               |
| `onRemoteVend(int avail_funds, int product_code, int options)` | Triggered when the device receives a remote vend command, providing the available funds, product code, and options for dispensing the product.                                                                        |
| `onReceipt(int ereceipt_type, String data)`                    | Called when a QR code receipt is generated, passing the QR code data to the peripheral to display for the consumer. (See Marshall Protocol section 8.12)                                                              |

## Vending Events Enumeration

<Warning>
  **C SDK Only**

  The enumeration described in this section is relevant for the **C** SDK only.
</Warning>

The `vmc_vend_event_e` enumeration is designed to handle events related to vending operations in the C SDK.

```c C theme={null}
Enum vmc_vend_event_e
```

### Enumeration Methods

Below is a list of methods available when using the `vend_callbacks_t` interface:

| Method                                                   | Description                                                                                                                                                                       |
| :------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `onReady(vend_session_t session)`                        | Called when the peripheral framework is ready to start a session. This occurs after a link has been established or a previous session has ended.                                  |
| `onSessionBegin(int fundsAvail)`                         | Called when a client presents a credit card, providing the available funds for the transaction.                                                                                   |
| `onTransactionInfo(vend_session_data_t data)`            | Triggered when transaction data is received, passing detailed information about the current session.                                                                              |
| `onVendApproved(vend_session_t session)`                 | Called when a vending request is approved, providing session details for further processing.                                                                                      |
| `onVendDenied(vend_session_t session)`                   | Called when a vending request is denied, passing relevant session details.                                                                                                        |
| `onSessionCanceled(vend_session_t session)`              | Triggered when a transaction is canceled, providing information about the canceled session.                                                                                       |
| `onSettlement(uint32_t success)`                         | Indicates the settlement status of a transaction. The success parameter indicates whether the settlement was successful (non-zero for success).                                   |
| `onStatus(uint32_t status)`                              | Called when the peripheral receives a `Status` command from Nayax's device. (See Marshall Protocol section 8.11)                                                                  |
| `onSessionsResponse(mdb_msg_sessions_status_t sessions)` | Triggered when the "Get Session Status" command is received from Nayax's device. Provides details about open sessions, helpful in multi-session mode or after a software restart. |
| `onReaderStateResponse(mdb_msg_reader_status_t state)`   | Responds to the "Get Reader Status" command, indicating whether the card reader is enabled or disabled. (See Marshall Protocol section 8.27.9)                                    |
| `onReceipt(int ereceiptType, String data)`               | Called when a QR code receipt is generated. Passes the QR code data to the peripheral to display for the consumer. (See Marshall Protocol section 8.12)                           |
| `onSessionTimeout(uint32_t sessionId)`                   | Triggered when a transaction times out, providing the `sessionId` of the timed-out session.                                                                                       |

## Why onVendDenied Carries No Reason

`onVendDenied` tells your peripheral that the vend was denied, but never why. That is deliberate. The machine is unattended, and surfacing a reason such as a blocked card on a public screen would embarrass the consumer.

The same applies to insufficient credit: the device does not show it and the SDK logs do not record it, because it concerns the exchange between the device and the acquirer rather than the exchange between the device and your machine.

You can see the reason a card was rejected or a transaction was cancelled in Nayax Core.

## Approve a Card with a Third-Party Server

When your peripheral authorizes proprietary cards against your own server, the flow runs outside the SDK up to the point of the verdict.

After the Vend Request is sent and the consumer presents a card, the device sends the Transfer Data command. Your peripheral receives the card details and forwards them to your server on its own. Once your server approves or denies the card, the peripheral reports the verdict back through `client_gateway_auth`, which also informs the device.

<CodeGroup>
  ```java Java theme={null}
  m_vmc.vend.client_gateway_auth(bool approved);
  ```

  ```csharp C# theme={null}
  vmc_instance.vend.client_gateway_auth(bool approved);
  ```

  ```c C theme={null}
  vmc_vend_client_gateway_auth(__bool approved)
  ```
</CodeGroup>

The demo apps simulate an approved card by returning `true`:

<CodeGroup>
  ```java Java theme={null}
  public void onSessionBegin(int funds_avail)
  {
      // credit card has been detected. stop timer
      session_timer_stop();

      // delayed vend example: send vend request later, and not now inside onBeginSession
      if (false)
          vend_timer_start();
      else
      {
          // vend request
          m_vmc.vend.vend_request(m_sessions[m_active_session]);

          // example: approve mifar/mag card externally (vmc authenticates)
          if (vmc_config.mag_card_approved_by_vmc_support || vmc_config.mifare_approved_by_vmc_support)
              m_vmc.vend.client_gateway_auth(true);
      }
  }
  ```

  ```csharp C# theme={null}
  public override void onSessionBegin(int funds_avail)
  {
      logger.d(TAG, "session began. requesting product vend");

      // do vend request
      vmc_instance.vend.vend_request(session);

      // todo: check if this is a mifare / mag card
      // todo: usually you will send this to another thread for async processing
      if (false)
      {
          // acknowledge mifare (note: only when machine is working on mifare/mag mode)
          if (vmc_config.mifare_approved_by_vmc_support || vmc_config.mag_card_approved_by_vmc_support)
              vmc_instance.vend.client_gateway_auth(true);
      }
  }
  ```

  ```c C theme={null}
  static void triggered_vend_request(void)
  {
  .
  .
  .
  if (config.mag_card_approved_by_vmc_support || config.mifare_approved_by_vmc_support || config.qr_approved_by_vmc_support)
  	{
  		vmc_vend_client_gateway_auth(__true);
  	}
  }
  ```
</CodeGroup>

## Cancel a Vend Request

Once you have sent a Vend Request and have not yet received Vend Approved or Vend Denied, you can send the Cancel command. It causes Vend Denied to be sent.

If Vend Approved was already on its way when you sent Cancel, the cancel does not appear in the logs, because a cancel cannot follow a Vend Approved. The peripheral sends Vend Failure instead. Responding with Vend Failure directly, without using Cancel, gives the same result.

You can also cancel before sending the Vend Request, when a consumer starts a transaction and then backs out. That covers both the case before a card is presented and the case just after Begin Session arrives but before you send the Vend Request. In the first case, the SDK log shows only `reader enable`.
