# Integrate custom payment gateways and methods

Source: https://developers.swell.is/guides/integrate-payment-gateways-methods

Swell supports numerous payment gateways, wallets, and alternative payment methods such as Stripe, Braintree, PayPal, and more. When you need a gateway or payment method that isn't natively supported, there are two approaches.

For a full gateway integration — cards collected in checkout, tokenization, and charges and refunds handled automatically by Swell — the recommended approach is to build a Swell app with a [payment extension](https://developers.swell.is/apps/extensions). See the [Build a payment gateway tutorial](https://developers.swell.is/apps/build-a-payment-gateway-tutorial) for a complete working example integrating Razorpay.

This guide covers the second approach: custom payment methods managed with the Backend API. This is a lighter-weight option suited to flows where payment happens outside of Swell checkout — such as bank transfers, invoicing, or redirect-based payments like Coinbase Commerce — where your own code records payments and refunds against orders. The following sections detail how to configure and manage custom payment methods, create payments using the Backend API, and handle refunds.

### Create the custom payment method

1. Login to the Swell dashboard and navigate to Settings > Payments.
1. Scroll down to the "Manual payments" section and click on the "Add manual payment method" button.
1. Select "Custom" from the dropdown and define the payment method name and ID. This is the ID you will use for the Frontend API and Backend API in order to update the cart billing method and post payments.

![An example of a custom payment method with the name "Coinbase"](https://cdn.sanity.io/images/ecf33d4l/production/3c33188879a733d0107a435ad6ec667dbf83741a-1322x1486.png)

### Hosted Checkout

In Hosted Checkout, custom payment methods appear as payment methods during the billing stage. Customers can then select this payment method and finalize the checkout.

If you require payment info from the customer, you’ll likely want to redirect the customer to a custom page in order to capture additional billing information related to the billing method. You can do so using the Customer return link in Settings > Checkout.

![An example showing a custom payment method named "Coinbase" on Swell's hosted checkout](https://cdn.sanity.io/images/ecf33d4l/production/7d398ba1a2117e3bae609f2dfe9da67c798d192b-1444x1800.png)

### Custom Checkout

If you’re building a custom checkout then you can define the exact payment flow for your custom payment method. Using the `id` of the payment method we created earlier, you can update a cart’s billing method using the `swell.cart.update()` method.

**Cart update**

**swell.js**

```javascript
await swell.cart.update({
	billing: {
		method: 'coinbase'
	}
});
```

If there is any specific billing info you would want to pass along to the order, you can update the cart’s `metadata` field.

**Cart update with metadata**

**swell.js**

```javascript
await swell.cart.update({
	metadata: {
		coinbase: {
			charge_code: 'FJE4T5'
		}
	}
});
```

You can then submit the cart with `swell.cart.submitOrder()` to create an order once all other customer data is captured.

#### Payments

Submitting the cart with `swell.cart.submitOrder()` will create an order with the billing method and metadata that was included in the cart. By default, orders created with custom payment methods do not have any payments associated to them and will have an `unpaid` status in the Swell dashboard.

Depending on the intended payment flow, you can use a webhook firing on the `order.created` event, or await for the response of the `submitOrder()` call in order to create payments.

To create payments, you’ll have to use the Backend API by posting to the `/payments` endpoint. Here’s an example payload for creating a payment using `swell-node` with a `coinbase` custom payment method.

**Posting a payment**

**Node**

```javascript
const { swell } = require('swell-node');
swell.init('STORE_ID', 'SECRET_KEY');

await swell.post('/payments', {
	amount: 30, //required
	method: 'coinbase', //required
	order_id: '6425a559c5aaf00012670aa9',
	account_id: '60a45168c19da965a5b399de',
	captured: true,
	authorized: true,
	charge_code: 'FJE4T5' //custom field that can be derived from order.metadata
});
```

Many of the fields in the snippet above are optional and are dependent on the gateway or payment method that you’re integrating. For a full list of fields and their descriptions, you can view the Payments model for more details.

#### Authorize & Capture

In the previous example we created a payment with both `authorized` and `captured` fields set to `true`. If you’d like to separate these steps to create an authorization prior to capture then you can follow the following directions:

Create a payment for an authorization, making sure to set `authorized: true` and `captured: false` to ensure you’re not capturing automatically.

**Creating an authorization**

**Node**

```javascript
const { swell } = require('swell-node');
swell.init('STORE_ID', 'SECRET_KEY');

await swell.post('/payments', {
	amount: 30, //required
	method: 'coinbase', //required
	order_id: '6425a559c5aaf00012670aa9',
	account_id: '60a45168c19da965a5b399de',
	captured: false,
	authorized: true,
	a_custom_field: "233dsd2asdw"
});
```

This would create a payment that would represent an authorization. When viewing this order in the admin dashboard, you’ll notice that the payment status is “Authorized” instead of “Paid”.

![A payment for an order with "Razorpay" payment gateway](https://cdn.sanity.io/images/ecf33d4l/production/cd23e6294836b58da5f04f815d6cfc866260c79c-1750x714.png)

You can then update the payment when the charge was captured by passing in `captured: true`

**Updating a payment**

**Node**

```javascript
const { swell } = require('swell-node');
swell.init('STORE_ID', 'SECRET_KEY');

await swell.put('/payments/<payment_id>', {
	captured: true,
});
```

After this request the order will now have a paid status that reflects the captured payment.

### Refunds

If you want to perform refunds from the admin dashboard, you will have to configure webhooks in order to manage the communication between Swell and the custom payment method or gateway you’ve configured.

To create a webhook:

1. Navigate to Settings > Webhooks
1. Select add webhook
1. Under events, select the `order.refunded` event
1. Add your webhook URL and save

Now when you’re viewing an order with an associated payment and select refund, you’ll receive the following payload:

**order.refunded payload example**

```json
{
    "user_id": "6059f83ea7a1d765d211b872",
    "type": "order.refunded",
    "data": {
        "payment_id": "642c671c57df50001226dfa9",
        "payment_refund_id": "642c672603fc0c0012735871",
        "id": "6426e581239bc700125dabac"
    },
    "model": "orders",
    "date_created": "2023-04-04T18:06:31.311Z",
    "date_updated": "2023-04-04T18:06:31.413Z",
    "webhooks_pending": 2,
    "id": "642c672703fc0c0012735878"
}
```

Querying the `/payments` endpoint with the provided `payment_id` would allow you to retrieve all the necessary data that was passed along when the payment was created. You can then interact with the payment gateway in order to process the requested refund.
