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

# Adyen - GCash

> Configure GCash via Adyen as a payment method in Gr4vy.

Adyen is a global payment technology company founded in 2006 in Amsterdam, Netherlands. The company provides a single platform for accepting payments across online, mobile, and in-store channels for major enterprises worldwide including Uber, Spotify, and Microsoft.

GCash is the leading mobile wallet in the Philippines. It allows buyers to pay using their GCash account balance, linked bank cards, and other funding sources. GCash supports one-time payments and recurring billing through its tokenization scheme.

## Setup

Please follow the [common Adyen instructions](./adyen) to get set up with GCash.

Next, make sure to enable GCash as a payment method on your configured account.

## Supported countries

Adyen supports transactions from buyers in `PH`.

## Supported currencies

Adyen supports processing payments in `PHP`.

## Integration

For GCash, the default integration for Adyen is through a redirect to a hosted payments page.

### Redirect integration

Start by creating a new transaction with the following required fields.

<CodeGroup>
  ```csharp C# theme={"system"}
  var transaction = await client.Transactions.CreateAsync(
    transactionCreate: new TransactionCreate()
    {
      Amount = 1299,
      Currency = "PHP",
      Country = "PH",
      Intent = "capture",
      PaymentMethod =
        TransactionCreatePaymentMethod.CreateRedirectPaymentMethodCreate(
          new RedirectPaymentMethodCreate()
          {
            Method = "gcash",
            Country = "PH",
            Currency = "PHP",
            RedirectUrl = "https://example.com/callback",
          }
        ),
    }
  );
  ```

  ```go Go theme={"system"}
  amount := int64(1299)
  currency := "PHP"
  country := "PH"
  method := components.RedirectPaymentMethodCreateMethodGcash
  redirectUrl := "https://example.com/callback"

  redirectPaymentMethodCreate := components.RedirectPaymentMethodCreate{
    Method: method,
    Country: country,
    Currency: currency,
    RedirectURL: redirectUrl,
  }
  paymentMethod := components.CreateTransactionCreatePaymentMethodRedirectPaymentMethodCreate(redirectPaymentMethodCreate)

  transactionCreate := components.TransactionCreate{
    Amount:        amount,
    Currency:      currency,
    Country:       &country,
    Intent:       gr4vy.Pointer(components.TransactionIntentCapture),
    PaymentMethod: &paymentMethod,
  }

  transaction, err := client.Transactions.Create(ctx, transactionCreate, nil, nil, nil)
  ```

  ```java Java theme={"system"}
  CreateTransactionResponse transactionResponse = gr4vyClient.transactions().create()
    .transactionCreate(TransactionCreate.builder()
      .amount(1299L)
      .currency("PHP")
      .country("PH")
      .intent(TransactionIntent.CAPTURE)
      .paymentMethod(TransactionCreatePaymentMethod.of(RedirectPaymentMethodCreate.builder()
        .method(RedirectPaymentMethodCreateMethod.GCASH)
        .country("PH")
        .currency("PHP")
        .redirectUrl("https://example.com/callback")
        .build()))
      .build())
    .call();

  Transaction transaction = transactionResponse.transaction().orElse(null);
  ```

  ```php PHP theme={"system"}
  $transactionCreate = new TransactionCreate(
    amount: 1299,
    currency: 'PHP',
    country: 'PH',
    intent: 'capture',
    paymentMethod: new RedirectPaymentMethodCreate(
      method: 'gcash',
      country: 'PH',
      currency: 'PHP',
      redirectUrl: 'https://example.com/callback'
    )
  );
  $response = self::$sdk->transactions->create($transactionCreate);
  $transaction = $response->transaction;
  ```

  ```python Python theme={"system"}
  transaction: models.Transaction = client.transactions.create(
    amount=1299,
    currency="PHP",
    country="PH",
    intent="capture",
    payment_method={
      "method": "gcash",
      "country": "PH",
      "currency": "PHP",
      "redirect_url": "https://example.com/callback",
    }
  )
  ```

  ```ts TypeScript theme={"system"}
  const transaction = await gr4vy.transactions.create({
    amount: 1299,
    currency: "PHP",
    country: "PH",
    intent: "capture",
    paymentMethod: {
      method: "gcash",
      country: "PH",
      currency: "PHP",
      redirectUrl: "https://example.com/callback"
    }
  })
  ```
</CodeGroup>

After the transaction is created, the API response includes `payment_method.approval_url` and the `buyer_approval_pending` status.

```json theme={"system"}
{
  "type": "transaction",
  "id": "ea1efdd0-20f9-44d9-9b0b-0a3d71e9b625",
  "payment_method": {
    "type": "payment-method",
    "approval_url": "https://cdn.sandbox.spider.gr4vy.app/connectors/adyen/apm.html?token=..."
  },
  "method": "gcash"
}
```

Redirect the buyer to the `approval_url` so they can complete authentication and approve the payment. After approval the buyer is redirected to the `redirect_url` you provided when creating the transaction. Do not rely solely on the redirect - either poll the transaction or (recommended) rely on webhooks to detect the final status (for example `capture_succeeded` or failure states).

### Direct integration

Adyen provides [web](https://docs.adyen.com/online-payments/build-your-integration/sessions-flow?platform=Web\&integration=Components\&version=6.23.0), [Android](https://docs.adyen.com/online-payments/build-your-integration/sessions-flow?platform=Android\&integration=Components\&version=5.15.0) and [iOS](https://docs.adyen.com/online-payments/build-your-integration/sessions-flow?platform=iOS\&integration=Components\&version=5.21.1) SDKs for a direct integration. For these flows you should indicate the platform by setting an appropriate `integration_client` when creating the transaction, and then build a client-side integration that uses the [`POST /transactions/:transaction_id/session`](/reference/transactions/get-transaction-session) API to initialize the Adyen SDK.

To start, create a new transaction with the appropriate `integration_client`.

<CodeGroup>
  ```csharp C# theme={"system"}
  var transaction = await client.Transactions.CreateAsync(
    transactionCreate: new TransactionCreate()
    {
      Amount = 1299,
      Currency = "PHP",
      Country = "PH",
      Intent = "capture",
      IntegrationClient = "ios",
      PaymentMethod =
        TransactionCreatePaymentMethod.CreateRedirectPaymentMethodCreate(
          new RedirectPaymentMethodCreate()
          {
            Method = "gcash",
            Country = "PH",
            Currency = "PHP",
            RedirectUrl = "yourapp://callback",
          }
        ),
    }
  );
  ```

  ```go Go theme={"system"}
  amount := int64(1299)
  currency := "PHP"
  country := "PH"
  integrationClient := "ios"
  method := components.RedirectPaymentMethodCreateMethodGcash
  redirectUrl := "yourapp://callback"

  redirectPaymentMethodCreate := components.RedirectPaymentMethodCreate{
    Method: method,
    Country: country,
    Currency: currency,
    RedirectURL: redirectUrl,
  }
  paymentMethod := components.CreateTransactionCreatePaymentMethodRedirectPaymentMethodCreate(redirectPaymentMethodCreate)

  transactionCreate := components.TransactionCreate{
    Amount:            amount,
    Currency:          currency,
    Country:           &country,
    Intent:           gr4vy.Pointer(components.TransactionIntentCapture),
    IntegrationClient: &integrationClient,
    PaymentMethod:     &paymentMethod,
  }

  transaction, err := client.Transactions.Create(ctx, transactionCreate, nil, nil, nil)
  ```

  ```java Java theme={"system"}
  CreateTransactionResponse transactionResponse = gr4vyClient.transactions().create()
    .transactionCreate(TransactionCreate.builder()
      .amount(1299L)
      .currency("PHP")
      .country("PH")
      .intent(TransactionIntent.CAPTURE)
      .integrationClient("ios")
      .paymentMethod(TransactionCreatePaymentMethod.of(RedirectPaymentMethodCreate.builder()
        .method(RedirectPaymentMethodCreateMethod.GCASH)
        .country("PH")
        .currency("PHP")
        .redirectUrl("yourapp://callback")
        .build()))
      .build())
    .call();

  Transaction transaction = transactionResponse.transaction().orElse(null);
  ```

  ```php PHP theme={"system"}
  $transactionCreate = new TransactionCreate(
    amount: 1299,
    currency: 'PHP',
    country: 'PH',
    intent: 'capture',
    integrationClient: 'ios',
    paymentMethod: new RedirectPaymentMethodCreate(
      method: 'gcash',
      country: 'PH',
      currency: 'PHP',
      redirectUrl: 'yourapp://callback'
    )
  );
  $response = self::$sdk->transactions->create($transactionCreate);
  $transaction = $response->transaction;
  ```

  ```python Python theme={"system"}
  transaction: models.Transaction = client.transactions.create(
    amount=1299,
    currency="PHP",
    country="PH",
    intent="capture",
    integration_client="ios",
    payment_method={
      "method": "gcash",
      "country": "PH",
      "currency": "PHP",
      "redirect_url": "yourapp://callback",
    }
  )
  ```

  ```ts TypeScript theme={"system"}
  const transaction = await gr4vy.transactions.create({
    amount: 1299,
    currency: "PHP",
    country: "PH",
    intent: "capture",
    integrationClient: "ios",
    paymentMethod: {
      method: "gcash",
      country: "PH",
      currency: "PHP",
      redirectUrl: "yourapp://callback"
    }
  })
  ```
</CodeGroup>

For mobile, set `integration_client` to `ios` or `android` and use your app deep link for `redirect_url` (for example, `yourapp://`).

After the transaction is created, the API response includes a `session_token` which can be used to get the [session data](/reference/transactions/get-transaction-session) for that transaction.

```sh theme={"system"}
POST /transactions/:transaction_id/session?token=:session_token
```

<CodeGroup>
  ```json Web theme={"system"}
  {
    "session_data": {
      "sessionId": "CS04C0B8AC9849A7D8E25B20D",
      "sessionData": "Ab02b4c0!BQABAgBLgbLpvkt1r3",
      "environment": "live",
      "clientKey": "client-key",
      "returnUrl": "https://example.com/callback",
      "paymentMethod": "gcash",
      "storePaymentMethod": true
    },
    "default_completion_url": "https://api.sandbox.spider.gr4vy.app/transactions/approve/some-token",
    "integration_client": "web"
  }
  ```

  ```json iOS theme={"system"}
  {
    "session_data": {
      "sessionId": "CS04C0B8AC9849A7D8E25B20D",
      "sessionData": "Ab02b4c0!BQABAgBLgbLpvkt1r3",
      "environment": "live",
      "clientKey": "client-key",
      "returnUrl": "yourapp://",
      "paymentMethod": "gcash",
      "storePaymentMethod": true
    },
    "default_completion_url": "https://api.sandbox.spider.gr4vy.app/transactions/approve/some-token",
    "integration_client": "ios"
  }
  ```

  ```json Android theme={"system"}
  {
    "session_data": {
      "sessionId": "CS04C0B8AC9849A7D8E25B20D",
      "sessionData": "Ab02b4c0!BQABAgBLgbLpvkt1r3",
      "environment": "live",
      "clientKey": "client-key",
      "returnUrl": "yourapp://",
      "paymentMethod": "gcash",
      "storePaymentMethod": true
    },
    "default_completion_url": "https://api.sandbox.spider.gr4vy.app/transactions/approve/some-token",
    "integration_client": "android"
  }
  ```
</CodeGroup>

This session data provides the `sessionId` and `sessionData` required to load the Adyen SDK.

<CodeGroup>
  ```js Web theme={"system"}
  const adyenEnvironment = sessionData.environment;
  const clientKey = sessionData.clientKey;
  const sessionId = sessionData.sessionId;
  const adyenSessionData = sessionData.sessionData;
  const returnUrl = sessionData.returnUrl;
  const paymentMethod = sessionData.paymentMethod;
  const storePaymentMethod = sessionData.storePaymentMethod;
  const configuration = {
      environment: adyenEnvironment,
      clientKey,
      analytics: {
        enabled: false,
      },
      session: {
        id: sessionId,
        sessionData: adyenSessionData,
      },
  }
  AdyenCheckout(configuration).then(function (checkout) {
    let component = checkout
      .create(paymentMethod)
      .mount('#component');
    });
  ```

  ```swift iOS theme={"system"}
  var adyenEnvironment = sessionData.environment;
  var clientKey = sessionData.clientKey;
  var sessionId = sessionData.sessionId;
  var adyenSessionData = sessionData.sessionData;
  var returnUrl = sessionData.returnUrl;
  var paymentMethod = sessionData.paymentMethod;
  var storePaymentMethod = sessionData.storePaymentMethod;

  override func viewDidLoad() {
    super.viewDidLoad()

    let configuration = AdyenSession.Configuration(sessionIdentifier: sessionId,
      initialSessionData: adyenSessionData)

    AdyenSession.initialize(with: configuration, delegate: self, presentationDelegate: self) { [weak self] result in
      switch result {
        case let .success(session):
            //Store the session object.
            self?.session = session
        case let .failure(error):
            //Handle the error.
      }
    }
  }
  ```

  ```kotlin Android theme={"system"}
  val adyenEnvironment = sessionData.environment;
  val clientKey = sessionData.clientKey;
  val sessionId = sessionData.sessionId;
  val adyenSessionData = sessionData.sessionData;
  val returnUrl = sessionData.returnUrl;
  val paymentMethod = sessionData.paymentMethod;
  val storePaymentMethod = sessionData.storePaymentMethod;

  // Create the session object
  val checkoutSession = CheckoutSession(
      session = Session(id = sessionId, sessionData = adyenSessionData),
      environment = Environment.TEST,
      clientKey = clientKey
  )

  when (result) {
      is CheckoutSessionResult.Success -> handleCheckoutSession(result.checkoutSession)
      is CheckoutSessionResult.Error -> handleError(result.exception)
  }
  ```
</CodeGroup>

#### Complete the transaction

<Badge color="green">Recommended</Badge>

On mobile integrations, after the buyer completes the payment flow, the Adyen SDK provides the developer with an `onFinished` call, which includes a `statusCode`.

The system automatically syncs the status through webhooks, but to complete the transaction it is also recommended sending a `GET` request to the `default_completion_url` provided in the session response with the `sessionId` and the `sessionResult` as query parameters to finalize the transaction. This also moves the transaction to a completed status without waiting for the webhook to be sent.

The call returns a `204 No Content` response. After receiving this response, you can also optionally fetch the transaction to confirm final status.

<CodeGroup>
  ```swift iOS theme={"system"}
  func didComplete(with result: AdyenSessionResult,
              component: Component,
              session: AdyenSession)
  {
      var urlComponents = URLComponents(string: defaultCompletionUrl)!
      urlComponents.queryItems = [
          URLQueryItem(name: "sessionId", value: session.session.id),
          URLQueryItem(name: "sessionResult", value: result.sessionResult)
      ]

      var request = URLRequest(url: urlComponents.url!)
      request.httpMethod = "GET"
      let task = URLSession.shared.dataTask(with: request) { data, response, error in
          // Handle 204 response, you can now poll the transaction
      }
      task.resume()
  }
  ```

  ```kotlin Android theme={"system"}
  override fun onFinished(result: SessionPaymentResult) {
      val sessionResult = result.sessionResult
      val uri = Uri.parse(defaultCompletionUrl)
          .buildUpon()
          .appendQueryParameter("sessionId", result.sessionId)
          .appendQueryParameter("sessionResult", sessionResult)
          .build()
      val url = URL(uri.toString())
      val urlConnection = url.openConnection() as HttpURLConnection
      urlConnection.requestMethod = "GET"
      val responseCode = urlConnection.responseCode
      if (responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
          // Handle 204 response, you can now poll the transaction
      }
  }
  ```
</CodeGroup>

Please refer to the Adyen documentation for the [web](https://docs.adyen.com/online-payments/build-your-integration/sessions-flow?platform=Web\&integration=Components\&version=6.23.0), [Android](https://docs.adyen.com/online-payments/build-your-integration/sessions-flow?platform=Android\&integration=Components\&version=5.15.0) and [iOS](https://docs.adyen.com/online-payments/build-your-integration/sessions-flow?platform=iOS\&integration=Components\&version=5.21.1) for further guidance.

## Recurring transactions

The Adyen GCash connector supports tokenized recurring payments. After a buyer authorizes the initial payment and their GCash wallet is stored, subsequent merchant-initiated charges are sent directly to Adyen using the stored payment method — no second redirect is required.

### Enrollment

To enroll a buyer in recurring transactions, create an initial transaction with tokenization enabled.

* Set `store` to `true` to save the payment method after the buyer approves.

<CodeGroup>
  ```csharp C# theme={"system"}
  var transaction = await client.Transactions.CreateAsync(
    transactionCreate: new TransactionCreate()
    {
      Amount = 1299,
      Currency = "PHP",
      Country = "PH",
      Intent = "capture",
      PaymentMethod =
        TransactionCreatePaymentMethod.CreateRedirectPaymentMethodCreate(
          new RedirectPaymentMethodCreate()
          {
            Method = "gcash",
            Country = "PH",
            Currency = "PHP",
            RedirectUrl = "https://example.com/callback",
          }
        ),
      Store = true,
    }
  );
  ```

  ```go Go theme={"system"}
  amount := int64(1299)
  currency := "PHP"
  country := "PH"
  method := components.RedirectPaymentMethodCreateMethodGcash
  redirectUrl := "https://example.com/callback"
  store := true

  redirectPaymentMethodCreate := components.RedirectPaymentMethodCreate{
    Method:      method,
    Country:      country,
    Currency:      currency,
    RedirectURL: redirectUrl,
  }
  paymentMethod := components.CreateTransactionCreatePaymentMethodRedirectPaymentMethodCreate(redirectPaymentMethodCreate)

  transactionCreate := components.TransactionCreate{
    Amount:        amount,
    Currency:      currency,
    Country:       &country,
    Intent:       gr4vy.Pointer(components.TransactionIntentCapture),
    PaymentMethod: &paymentMethod,
    Store:         &store,
  }

  transaction, err := client.Transactions.Create(ctx, transactionCreate, nil, nil, nil)
  ```

  ```java Java theme={"system"}
  CreateTransactionResponse transactionResponse = gr4vyClient.transactions().create()
    .transactionCreate(TransactionCreate.builder()
      .amount(1299L)
      .currency("PHP")
      .country("PH")
      .intent(TransactionIntent.CAPTURE)
      .paymentMethod(TransactionCreatePaymentMethod.of(RedirectPaymentMethodCreate.builder()
        .method(RedirectPaymentMethodCreateMethod.GCASH)
        .country("PH")
        .currency("PHP")
        .redirectUrl("https://example.com/callback")
        .build()))
      .store(true)
      .build())
    .call();

  Transaction transaction = transactionResponse.transaction().orElse(null);
  ```

  ```php PHP theme={"system"}
  $transactionCreate = new TransactionCreate(
    amount: 1299,
    currency: 'PHP',
    country: 'PH',
    intent: 'capture',
    paymentMethod: new RedirectPaymentMethodCreate(
      method: 'gcash',
      country: 'PH',
      currency: 'PHP',
      redirectUrl: 'https://example.com/callback'
    ),
    store: true
  );
  $response = self::$sdk->transactions->create($transactionCreate);
  $transaction = $response->transaction;
  ```

  ```python Python theme={"system"}
  transaction: models.Transaction = client.transactions.create(
    amount=1299,
    currency="PHP",
    country="PH",
    intent="capture",
    payment_method={
      "method": "gcash",
      "country": "PH",
      "currency": "PHP",
      "redirect_url": "https://example.com/callback",
    },
    store=True
  )
  ```

  ```ts TypeScript theme={"system"}
  const transaction = await gr4vy.transactions.create({
    amount: 1299,
    currency: "PHP",
    country: "PH",
    intent: "capture",
    paymentMethod: {
      method: "gcash",
      country: "PH",
      currency: "PHP",
      redirectUrl: "https://example.com/callback"
    },
    store: true
  })
  ```
</CodeGroup>

Redirect the buyer to the `approval_url` to complete the GCash authorization flow. After the buyer approves, Adyen delivers the stored payment method token through a `recurring.token.created` webhook. Rely on webhooks rather than the redirect to confirm that the token is ready for subsequent charges.

### Subsequent payment

After the payment method is stored, create each recurring charge using the saved payment method ID. Gr4vy routes the charge directly to Adyen without requiring a buyer redirect.

* Set `payment_method.method` to `id` and pass the saved payment method ID.
* Set `payment_source` to `recurring`.
* Set `merchant_initiated` and `is_subsequent_payment` to `true`.

<CodeGroup>
  ```csharp C# theme={"system"}
  var transaction = await client.Transactions.CreateAsync(
    transactionCreate: new TransactionCreate()
    {
      Amount = 1299,
      Currency = "PHP",
      Country = "PH",
      Intent = "capture",
      PaymentMethod = TransactionCreatePaymentMethod.CreateTokenPaymentMethodCreate(
        new TokenPaymentMethodCreate()
        {
          Id = "f758d736-9a81-4bd0-85a9-2d3ee361b863"
        }
      ),
      IsSubsequentPayment = true,
      MerchantInitiated = true,
      PaymentSource = "recurring",
    }
  );
  ```

  ```go Go theme={"system"}
  amount := int64(1299)
  currency := "PHP"
  country := "PH"
  paymentSource := components.TransactionPaymentSourceRecurring

  tokenPaymentMethodCreate := components.TokenPaymentMethodCreate{
    ID: "f758d736-9a81-4bd0-85a9-2d3ee361b863",
  }
  paymentMethod := components.CreateTransactionCreatePaymentMethodTokenPaymentMethodCreate(tokenPaymentMethodCreate)

  transactionCreate := components.TransactionCreate{
    Amount:              amount,
    Currency:            currency,
    Country:             &country,
    Intent:             gr4vy.Pointer(components.TransactionIntentCapture),
    PaymentMethod:       &paymentMethod,
    IsSubsequentPayment: gr4vy.Bool(true),
    MerchantInitiated:   gr4vy.Bool(true),
    PaymentSource:       &paymentSource,
  }

  transaction, err := client.Transactions.Create(ctx, transactionCreate, nil, nil, nil)
  ```

  ```java Java theme={"system"}
  CreateTransactionResponse transactionResponse = gr4vyClient.transactions().create()
    .transactionCreate(TransactionCreate.builder()
      .amount(1299L)
      .currency("PHP")
      .country("PH")
      .intent(TransactionIntent.CAPTURE)
      .paymentMethod(TransactionCreatePaymentMethod.of(TokenPaymentMethodCreate.builder()
        .id("f758d736-9a81-4bd0-85a9-2d3ee361b863")
        .build()))
      .isSubsequentPayment(true)
      .merchantInitiated(true)
      .paymentSource(TransactionPaymentSource.RECURRING)
      .build())
    .call();

  Transaction transaction = transactionResponse.transaction().orElse(null);
  ```

  ```php PHP theme={"system"}
  $transactionCreate = new TransactionCreate(
    amount: 1299,
    currency: 'PHP',
    country: 'PH',
    intent: 'capture',
    paymentMethod: new TokenPaymentMethodCreate(
      id: 'f758d736-9a81-4bd0-85a9-2d3ee361b863'
    ),
    isSubsequentPayment: true,
    merchantInitiated: true,
    paymentSource: 'recurring'
  );
  $response = self::$sdk->transactions->create($transactionCreate);
  $transaction = $response->transaction;
  ```

  ```python Python theme={"system"}
  transaction: models.Transaction = client.transactions.create(
    amount=1299,
    currency="PHP",
    country="PH",
    intent="capture",
    payment_method=models.TokenPaymentMethodCreate(
      id="f758d736-9a81-4bd0-85a9-2d3ee361b863"
    ),
    is_subsequent_payment=True,
    merchant_initiated=True,
    payment_source="recurring"
  )
  ```

  ```ts TypeScript theme={"system"}
  const transaction = await gr4vy.transactions.create({
    amount: 1299,
    currency: "PHP",
    country: "PH",
    intent: "capture",
    paymentMethod: {
      method: "id",
      id: "f758d736-9a81-4bd0-85a9-2d3ee361b863"
    },
    isSubsequentPayment: true,
    merchantInitiated: true,
    paymentSource: "recurring"
  })
  ```
</CodeGroup>

### Cancellation

To revoke a stored GCash payment method, use the standard [Delete payment method](/reference/payment-methods/delete-payment-method) endpoint with the saved payment method ID.

## Testing

Adyen has [instructions](https://docs.adyen.com/payment-methods/gcash/#test-and-go-live) on how to test GCash.
