Velo Tutorial: Payment Provider Custom Extension

Wix custom extensions allow you to expand what your site can do by integrating with 3rd-party services not currently supported by Wix. They also allow you to implement custom logic to change how your site displays and behaves using Velo. Learn more about Custom App Extensions Using SPIs.

Custom extensions are implemented using Velo SPIs. You can manage extended services from your site's dashboard, and they behave just like the ones Wix already supports.

With the payment provider custom extension, you can integrate your site with payment providers that aren't currently supported by Wix. You can also customize the transaction and refund flows to match your site's specific needs.

This guide explains how to set up a payment provider custom extension on your site using Velo.

The process has 3 steps:

  1. Create a new payment provider extension on your site.
  2. Implement your extension with custom code.
  3. Deploy the extension.

Note:
This feature is still in beta testing and may change significantly before the final release.

Step 1: Create a new payment provider extension

The first step in setting up your new extension is to add it to your site. This process creates a new folder in the Custom Extensions section of the Velo Sidebar that contains the files for your code.

  1. With Velo Dev Mode enabled, click Public & Backend on the Velo Sidebar.

  2. Scroll down to Custom Extensions.

  3. Hover over Custom Extensions and click .

  4. Select New Payment Extension.

  5. Click Start Now.

  6. Select I understand the Terms & Conditions and click Accept.

  7. Enter a name for your extension and click Add & Edit Code.

    The name can't contain spaces or special characters.

Step 2: Implement the extension

The procedure in the previous section creates a folder in the Custom Extensions section of the Velo Sidebar called payment-provider. Inside this is another folder with the name of the extension you set up. This folder contains 2 files, -config.js and .js.

To implement your extension, you need to:

  • Add custom code in these files to integrate with a payment provider.
  • Expose HTTP endpoints on your site that the payment provider can use to send your site updates about transactions and refunds.

Here are some guidelines for writing your code:

<my-extension-name>-config.js

The code in this file defines a function named getConfig() that returns an object containing the values used to display information about your extension in 3 different locations on your site:

  1. The Connect page where you connect a payment provider to your site.

  2. The Accept Payments page where you see the payment methods you've connected to your site.

  3. The Checkout page where your site visitors finalize their shipping and payment details and place orders.

The object returned by getConfig() includes the following properties:

  • title: (required) The name of the payment service provider as a string. This name is displayed when selecting payment providers to connect to on your site's dashboard.

  • paymentMethods: (required) An array of paymentMethod objects defining the different payment methods supported by this provider. Each payment method object has a key whose value is the name of payment method. For now, only 'hostedPage' is supported. The value of this key is an object that can include the following properties:

    • title: (required) The payment method title as a string. This title is used to display the payment method on your site's dashboard.

    • logos: An object containing URLs to the payment method's logo as strings. These logos are displayed on the site's dashboard and the checkout cart. You can provide different logos for white and colored backgrounds. See the example return object below for details.

    • billingAddressMandatoryFields: An array of strings representing the billing address fields that buyers must include in order to use this payment method.

      Options: 'ZIPCODE', 'CITY', 'STATE', 'ADDRESS', 'COUNTRY_CODE', 'EMAIL', 'PHONE', 'FIRST_NAME', 'LAST_NAME', 'STREET', 'HOUSE_NUMBER', 'TAX_IDENTIFIER'

  • credentialsFields: (at least 1 credentials object is required) An array of objects representing the credentials required to connect an account for the payment provider. The credentials fields are displayed on the Connect page in your site's dashboard. The following credentials objects are supported:

    • simpleField: An object representing a text field.

      • name: The key to use for the field in your code as a string.
      • label: The label of the field to display on the dashboard as a string.
    • checkboxField: An object representing a checkbox field.

      • name: The key to use for the field in your code as a string.
      • label: The label of the field to display on the dashboard as a string.
      • tooltip: Tooltip text to display when the user hovers over the field as a string.
    • dropdownField: An object representing a dropdown field.

      • name: The key to use for the field in your code as a string.

      • label: The label of the field to display on the dashboard as a string.

      • options: An array of objects representing the options to display in the dropdown field. Each options object contains the following properties:

        • key: The name of the option to use in your code as a string.

        • value: The label of the option to display on the dashboard as a string.

Example return object:

Copy
1
{
2
title: 'Banana Payments',
3
paymentMethods: [{
4
hostedPage: {
5
title: 'Banana Payments',
6
billingAddressMandatoryFields: ['CITY'],
7
logos: {
8
white: {
9
svg: 'https://static.wixstatic.com/shapes/94b5e2_403ceb582027431cb92f38fd18d1843c.svg',
10
png: 'https://freesvg.org/img/15930333081593032446pitr_Bananas_icon.png'
11
},
12
colored: {
13
svg: 'https://static.wixstatic.com/shapes/94b5e2_403ceb582027431cb92f38fd18d1843c.svg',
14
png: 'https://freesvg.org/img/15930333081593032446pitr_Bananas_icon.png'
15
}
16
}
17
}
18
}],
19
credentialsFields: [{
20
simpleField: {
21
name: 'clientId',
22
label: 'API id'
23
}
24
},
25
{
26
simpleField: {
27
name: 'clientSecret',
28
label: 'API secret'
29
}
30
}]
31
}

<my-extension-name>.js

The code in this file defines the connectAccount(), createTransaction() and refundTransaction() functions. These functions are called by Wix at different points in the payment processing flow. The following sections describe the usage, parameters, and return values of these functions.

connectAccount()

This function is called when you click the Connect button on the Connect page in your site's dashboard. You can use it to create a new account for the payment provider you want to connect to, and return the account information to Wix. The function accepts the following parameters:

options: An object containing the credentials you entered on the Connect page together with other information about the site that you might need to connect to the payment provider. For more details, see the SPI Reference.

Example options object:

Copy
1
{
2
credentials: {
3
client_id: 'da5a42c8914a-568-4d-5f25b-44438d6a',
4
client_secret: '38d6a2c5f25b8-568-4d-914a-da5a4444'
5
},
6
country: 'US',
7
currency: 'USD',
8
wixMerchantId: '3e01ddt8-134e-4dd7-a28f-ht6jf276c876'
9
}

Note:
This function has a second parameter called context. This parameter is for internal Wix use only. You don't need to use it in your code.

The createAccount() function must return an object containing the account information and credentials for the payment provider you're connecting to. Wix uses the return values from this function to set up the payment provider on your site. The account credentials returned by this function are also passed to your extension's createTransaction() and refundTransaction() functions. This way, you can use them to make requests to the payment provider's API. If the payment provider fails to create an account, return an error object instead of the account details. For more details, see the SPI Reference.

Example return value:

Copy
1
{
2
credentials: {
3
client_id: 'da5a42c8914a-568-4d-5f25b-44438d6a',
4
client_secret: '38d6a2c5f25b8-568-4d-914a-da5a4444'
5
},
6
accountId: '1o3k5234-2342kk334',
7
accountName: 'john@doe.com'
8
}

createTransaction()

This function is called when a site visitor clicks the Place Order button on your site's Checkout page. Use it to send a request to a payment provider to create a new transaction. The function accepts the following parameters:

options: An object containing information about your site, the site visitor's order, and redirect URLs for payment processing. For more details, see the SPI Reference.

Example options object:

Copy
1
{
2
"wixTransactionId": "6b264d6f-f54e-426a-a8ed-b6f103c86d46",
3
"paymentMethod": "385f25b8-79c0-4d44-914a-d6568a2cda5a",
4
"merchantCredentials": {
5
"client_id": "da5a42c8914a-568-4d-5f25b-44438d6a",
6
"client_secret": "38d6a2c5f25b8-568-4d-914a-da5a4444"
7
},
8
"order": {
9
"_id": "fb591a7c-8471-464a-a64c-181c449b07ed",
10
"description": {
11
"billingAddress": {
12
"city": "New York",
13
"email": "jane@doe.com",
14
"state": "NY",
15
"zipCode": "10014",
16
"lastName": "Jane",
17
"firstName": "Doe",
18
"countryCode": "US",
19
"address": "100 Gansevoort St",
20
"phone": "212-555-0100"
21
},
22
"items": [
23
{
24
"_id": "baeb40f5-a48a-4424-cec2-253c9772ad42",
25
"name": "Banana shirt",
26
"quantity": 1,
27
"price": "10000"
28
}
29
],
30
"totalAmount": "10000",
31
"charges": {},
32
"buyerInfo": {
33
"buyerId": "9b5d1bed-6a1d-4980-9d2e-82713fb6bf0e",
34
"buyerLanguage": "en"
35
},
36
"currency": "EUR",
37
"shippingAddress": {
38
"city": "New York",
39
"email": "jane@doe.com",
40
"state": "NY",
41
"zipCode": "10014",
42
"lastName": "Jane",
43
"firstName": "Doe",
44
"countryCode": "US",
45
"address": "100 Gansevoort St",
46
"phone": "212-555-0100"
47
}
48
},
49
"returnUrls": {
50
"successUrl": "https://cashier-services.wix.com/_api/payment-services-web/redirect/success/b5f106b4-f78e-426a-a8ed-3c76d4696d6f",
51
"errorUrl": "https://cashier-services.wix.com/_api/payment-services-web/redirect/error/b5f106b4-f78e-426a-a8ed-3c76d4696d6f?pmName=EmptyPayment&pmUrl=&failureCode=6000",
52
"cancelUrl": "https://cashier-services.wix.com/_api/payment-services-web/redirect/cancel/b5f106b4-f78e-426a-a8ed-3c76d4696d6f",
53
"pendingUrl": "https://cashier-services.wix.com/_api/payment-services-web/redirect/pending/b5f106b4-f78e-426a-a8ed-3c76d4696d6f"
54
}
55
},
56
"wixMerchantId": "ed2bfda6-134e-4cc9-a37f-756c6843e01d",
57
"fraudInformation": {
58
"remoteIp": "145.231.63.45"
59
}
60
}

Note:
This function has a second parameter called context. This parameter is for internal Wix use only. You don't need to use it in your code.

The createTransaction() function must return an object with a pluginTransactionId property that represents payment provider's ID for the created transaction. Other properties may be included depending on the type of transaction you're creating and the results of the request. For more details, see the SPI Reference.

Example return value:

Copy
1
{
2
"pluginTransactionId": "e89b-12d3-a456-42665",
3
"redirectUrl": "https://www.example.com/redirect"
4
}

To receive updates from the payment provider about the success or failure or the transaction, expose an HTTP endpoint for this purpose. Provide the URL to the payment provider as part of the request to create the transaction. Use the submitEvent() function to in the logic for your endpoint to mark the transaction as completed. Once this happens, the order associated with the transaction appears in the Orders tab in your site's dashboard.

refundTransaction()

This function is called when you initiate the refund of a transaction from your connected payment provider on the Orders tab in your site's dashboard. Use this function to send a request to the payment provider to create a refund for the transaction. The function accepts the following parameters:

options: An object containing information about the transaction being refunded and the refund amount. For more details, see the SPI Reference.

Example options object:

Copy
1
{
2
"wixTransactionId": "6b264d6f-f54e-426a-a8ed-b6f103c86d46",
3
"pluginTransactionId": "e89b-12d3-a456-42665",
4
"wixRefundId": "4j7lk09d-0ok8-edh5-hj89-1kg9ds8n50lo9",
5
"merchantCredentials": {
6
"client_id": "da5a42c8914a-568-4d-5f25b-444"
7
},
8
"refundAmount": 10000,
9
"reason" : "REQUESTED_BY_CUSTOMER"
10
}

Note:
This function has a second parameter called context. This parameter is for internal Wix use only. You don't need to use it in your code.

The refundTransaction() function must return an object with a pluginRefundId property that represents the ID of the refund created by the payment provider. If the request to the payment provider isn't approved, the return object should include information about why this happened. For more details, see the SPI Reference.

Example return value for a successful refund:

Copy
1
{
2
"pluginRefundId": "e89b-12d3-a456-42665"
3
}

Example return value for a failed refund:

Copy
1
{
2
"pluginRefundId": "e89b-12d3-a456-42665",
3
"reasonCode": 3025,
4
"errorCode": "INSUFFICIENT_FUNDS_FOR_REFUND",
5
"errorMessage": "Insufficient funds for refund"
6
}

To receive updates from the payment provider about the refund, expose an HTTP endpoint for this purpose. Provide the URL to the payment provider as part of the request to create the refund. Use the submitEvent() function in the logic for your endpoint to mark the refund as completed. Once this happens, the order associated with the refund is marked as refunded on you site's dashboard.

HTTP Endpoints

When you create a transaction or refund with your payment provider, you need to supply a URL for an HTTP endpoint that the provider can use to send your site updates for the statuses of transactions and refunds. To expose these endpoints on your site, use the Wix HTTP Functions API. In the code for these endpoints, use the submitEvent() function to update the statuses of transactions and refunds on your site.

Example endpoint code. This code must be saved in a backend file called http-functions.js:

Copy
1
import wixPaymentProviderBackend from 'wix-payment-provider-backend';
2
3
// An endpoint for receiving updates about transactions.
4
export async function post_updateTransaction(request) {
5
const transactionRequestBody = await request.body.json()
6
const response = {
7
'headers': {
8
'Content-Type': 'application/json'
9
}
10
};
11
// Validate the request content.
12
if (transactionRequestBody.state === 'Payment_Received') {
13
// Update the transaction status on your site. This code assumes that the Wix
14
// transaction ID and the payment provider's transaction ID are included in
15
// the URL as query parameters.
16
await wixPaymentProviderBackend.submitEvent({
17
'event': {
18
'transaction': {
19
'wixTransactionId': request.query['wixTransactionId'],
20
'pluginTransactionId': request.query['pluginTransactionId']
21
}
22
}
23
})
24
return ok(response);
25
} else {
26
return badRequest(response);
27
}
28
}
29
30
// An endpoint for receiving updates about refunds.
31
export async function post_updateRefund(request) {
32
const refundRequestBody = await request.body.json()
33
const response = {
34
'headers': {
35
'Content-Type': 'application/json'
36
}
37
};
38
// Validate the request content.
39
if (refundRequestBody.state === 'approved') {
40
// Update the refund status on your site. This code assumes that Wix
41
// transaction and refund IDs as well as other refund information are
42
// included in the URL as query parameters.
43
await wixPaymentProviderBackend.submitEvent({
44
'event': {
45
'refund': {
46
'wixTransactionId': request.query['wixTransactionId'],
47
'wixRefundId': request.query['wixRefundId'],
48
'pluginRefundId': refundRequestBody.reference_id,
49
'amount': request.query['amount']
50
}
51
}
52
})
53
return ok(response);
54
} else {
55
return badRequest(response);
56
}
57
}

Add files to an extension

If you don't want to keep all of your code in the main extension files, you can add files to the extension's folder and import functions and objects into the main files.

  1. Hover over the extension folder's name and click More Actions .
  2. Select New .js file.
  3. To import from these files to the main extension files, use the following syntax:
Copy
1
import { functionName } from './myFileName.js';

Test an extension

You can test your extension before publishing your site using functional testing like you would with any backend Velo code. Make sure your createAccount(), createTransaction(), and refundTransaction() functions' return values are properly formatted. To test your extension after deploying, add console logs to your code. The results appear in the Site Events log.

Step 3: Deploy the extension

Once your code files are ready, you need to deploy your extension and enable it on your site's dashboard.

  1. Publish your site.

  2. Go to the Accept Payments settings on your site's dashboard.

  3. Click See More Payment Options.

  4. Find the payment provider from your custom extension in the list and click Connect.

  5. Enter the account credential information for the payment provider and click Connect.

  6. Once your custom extension is deployed, the new payment provider appears on your site's Checkout page.

Example Integration

The payment provider custom extension allows you to implement a variety of different transaction flows. We created a sample site that demonstrates a basic transaction and refund integration with Tazapay.

Note:
Clicking the link to the sample site opens a copy of the site. Publishing the copy adds it to your Wix account.

In order to get your copy of the sample site working, you need to create and save a Tazapay API key, and make some small changes to the site's code.

Create and save a Tazapay API key

Do the following to generate a Tazapay API key and use it to connect Tazapay as a payment provider on your copy of the sample site:

  1. Publish a copy of the template site to save it to your Wix account.

  2. Sign up for a free Tazapay sandbox account and log in.

  3. On your Tazapay dashboard, click API keys.

    An API key and API secret are generated. Copy these values.

  4. Open the Tazapay API Reference.

  5. Under Authentication, enter your API key for username and your API secret for password. Your API authorization token, starting with Basic, is displayed in the sample request panel. Copy the token.

  6. Open the Accept Payments page for your copy of the sample site.

  7. Click See More Payment Options.

  8. Find the Tazapay payment provider and click Connect.

  9. Enter your API authorization token in the API Auth Token field.

  10. Click Connect.

Code setup

Make the following 2 changes to your sample site's code to get it working:

  1. On the Velo sidebar, click Public & Backend .

  2. Under Custom Extensions, select payment-provider > Tazapay > Tazapay.js.

  3. In the createCheckoutSession function, change the value of callbackUrl to reflect the details of your site. Change <my-account> to your Wix account name and <my-site-name> to the name of your copy of the sample site.

  4. Make the same changes to the callbackUrl value in the createRefund function.

  5. Publish your site.

Was this helpful?
Yes
No