# Generate Invoice Link

RKFL create an invoice in their system before processing the payment. Once the payment is processed, the invoice turns into an order.&#x20;

The merchant website must send the cart info to RKFL for creating an invoice. The API returns a redirect URL with a UUID. The merchant website can save this redirect URL for future purposes.&#x20;

There are two ways of integration

1. Redirect: If merchant wants to use redirect approach, they can redirect shopper to the redirect link
2. Widget (Popup): In case merchant wants to use inline experience(without redirection), they can use UUID with JavaScript SDK. See here for the [Javascript SDK Documentation](#rocketfuel-js-sdk)&#x20;

The RKFL also supports recurring payments on subscribed products. If the shopper subscribed to a product and paid from the connected exchange, the RKFL can manage the recurring payment on the defined frequency and update the merchant server through a registered webhook. The subscription facility is only available on exchange payment.&#x20;

The request payload also supports receiving some custom parameters from the merchant website. These custom parameters will return in the transaction status update webhook. The merchant can also define the HTTP method (GET/POST) to receive the webhook.

{% hint style="info" %}
The length of the complete payload, including the custom parameters, must not exceed the max length of "GET" and "POST" requests.

The max length of the "GET" request is 2048 characters, and the max length of the "POST" request is 2M.
{% endhint %}

The merchants who want to integrate the RKFL-hosted checkout experience redirect the shopper to this URL.

> The RKFL-hosted checkout page is the simplest way to use the RKFL services

### Subscription

To add a subscription product to the invoice, you must pass additional details with the product object in the cart.

These details include &#x20;

"isSubscription" - This should be set to true if the product is a subscription product

"frequency" - This describes how frequently the subscription will be charged

"subscriptionPeriod" - The duration for which the subscription will be active

"merchantSubscriptionId" -  The unique subscription Id generated by the merchant

```
// Here is the sample of the request payload. 
{
  "amount": "",
  "cart":[{
    "id": "",
    "price": "",
    "name": "",
    "quantity": "",
    "key": "",
    "totalPrice": "",
    //only add the below, if the product is a subscription item.
    "isSubscription": "", 
    "frequency": "",
    "subscriptionPeriod":""
    "merchantSubscriptionId": "",
    "autoRenewal": true/false, // pass false on null for subscription item
  }],
  "currency": "",
  "order": "",
  "redirectUrl": "",
   "customParameter": {
    "returnMethod": "POST/GET",
    "params": [
      {
        "name": "var",
        "value": "1302*6649c8793fa687fe708618ae52344e26*1685*2*1*128*76"
      },
      {
          "name": "custom",
          "value": "1302|6649c8793fa687fe708618ae52344e26|2|1|128|2|1685"
      }
    ]
  },
  customerInfo{
    name: required (string)
    email: required (string)
    phone: optional (string)
    address: optional (string)
  },
  shippingAddress{
    firstname:optional (string)
    lastname: optional (string)
    phoneNo: optional (string)
    address1: required (string)
    address2: optional (string)
    state: required (string)
    city: required (string)
    zipcode: optional (string)
    country: required (string)
    landmark: optional (string)
    email: optional (string)
  }
}

// isSubscription: true/false 
// subscriptionPeriod: [number][period] - for example 1y, 2m, 3w
// autoRenewal: true/false // if false is passed merchants can manage the debit of subscription items 
  on their own or if passed true Rocketfuel will manage the subscriptions based on the frequency passed.
// frequency: weekly/monthly/quarterly/half-yearly/yearly
// merchantSubscriptionId: Subscription id for merchant system. This key will use to communicate the recurring payment status.
// If no shipping details are available, shippingAddress can be assigned null
i.e., shippingAddress : null
```

{% hint style="info" %}
You can use **siteInfo** in the parameter to generate invoices from different websites/stores.
{% endhint %}

<mark style="color:green;">`POST`</mark> `/hosted-page`

#### Headers

| Name                                              | Type   | Description                      |
| ------------------------------------------------- | ------ | -------------------------------- |
| "authorization"<mark style="color:red;">\*</mark> | String | "Bearer" + merchant access token |
| "Content-Type"                                    | String | "application/json"               |

#### Request Body

| Name                                       | Type   | Description                                                                                        |
| ------------------------------------------ | ------ | -------------------------------------------------------------------------------------------------- |
| amount<mark style="color:red;">\*</mark>   | String |                                                                                                    |
| cart<mark style="color:red;">\*</mark>     | Object | id, price, name, quantity, key, totalPrice, isSubscription, frequency, merchantSubscriptionId      |
| currency<mark style="color:red;">\*</mark> | String | USD/EUR                                                                                            |
| order                                      | String | Unique order id from the merchant's system                                                         |
| redirectUrl                                | String | Return URL of merchant's website, in case of RKFL hosted checkout integrated                       |
| customerInfo                               | Object | name, email, phone, address                                                                        |
| shippingAddress                            | Object | firstname, lastname, phoneNoaddress1, address2, state, city, zipcode, country, landmark, email     |
| customParameter                            | Object | returnMethod could be GET or POST only. The supplied custom parameters will return in the webhook. |
| merchant\_id                               | String | Unique merchant ID which each merchant has                                                         |
| siteInfo                                   | Object | siteUrl, siteName, siteLogo                                                                        |

{% tabs %}
{% tab title="200: OK Success" %}

```javascript
{
    "ok":true,
    "result":{
        "url":"https://payments-sandbox.rocketfuelblockchain.com/hostedPage/f7cb4141-3030-4245-8aa1-f5cf95b5d504",
        "uuid": "f7cb4141-3030-4245-8aa1-f5cf95b5d504"
    }
}
```

{% endtab %}
{% endtabs %}

## RocketFuel JS SDK

Follow the guide to embed RocketFuel Hosted Page on the Merchant's website.

## Prerequisites:-

Merchant should send below JSON input details to display the same on RocketFuel hosted page

```
Sample Format of JSON Data-
{
    amount: "11.00",
    merchant_id: process.env.MERCHANT_ID,
    cart: [
    {
	    id: "23",
	    name: "Album",
	    price: "11",
	    quantity: "1",
    },
    ],
	 currency: "USD",
    order: "390",
    redirectUrl: "",
}
```

where

1. Amount - total price of whole order for payment, in USD only
2. Cart -\
   a. ID - Article unique Id\
   b. Name - Article Name\
   c. Price - Article price\
   d. Quantity - Article Quantity
3. Currency - Currency in which Merchant recieved the payment, in USD only
4. Order - Unique Order Id
5. RedirectUrl - URL of the Merchant site where the Merchant wants to redirect from the Hosted page to their site after payment.

#### Follow the steps below :-

1. Merchant need to be authenticated on RocketFuel by passing the input parameters - MERCHANT\_EMAIL and MERCHANT\_PASSWORD.

**Request**

```
var options = {
	method: "POST",
	url: process.env.API_ENDPOINT + "auth/login",
    headers: {
	    "Content-Type": "application/json",
    },
    body: JSON.stringify({
	    email: process.env.MERCHANT_EMAIL,
	    password: process.env.MERCHANT_PASS,
    }),
};
```

**Response**

```
{ "ok":true, "result"{ "access":"eyJhbGciOiJIUzI1NiIsInR5cCI6Ikp
XVCJ9.eyJpZCI6ImViMDE1NWU4 LTkwNzItNGMyYi05NWFjLTAxZDhiMWFlZDI3ZC
IsImlhdCI6MTYyMzQwMz g0OSwiZXhwIjoxNjIzNDkwMjQ5fQ.t1wL6LYkr8y5sau
CuOWMmGbGNDZH qXzUjo6WeT370c","refresh":"eyJhbGciOiJIUzI1NiIsInR5
cCI6IkpXVCJ9.eyJpZC I6ImViMDE1NWU4LTkwNzItNGMyYi05NWFjLTAxZDhiMWF
lZDI3ZCIsImlhd CI6MTYyMzQwMzg0OSwiZXhwIjoxNjI1OTk1ODQ5fQ.A_JF1ODt
cRCRc7Yn TcT5JBFDDMkgQtlQXYkhBFw3dgM", "status":2 }
```

2\. Once Merchant is verified, details of the items purchased with the access token will be sent in a different request.

Note - Token needs to send in the Header and details of the items purchased in the Body.

**Request**

```
var options = {
    method: "POST",
    url: process.env.API_ENDPOINT + "hosted-page",
    headers: {
	    authorization: "Bearer " + accessToken,
	    "Content-Type": "application/json",
    },
    body: JSON.stringify({
    amount: "11.00",
    merchant_id: process.env.MERCHANT_ID,
    cart: [
    {
	    id: "23",
	    name: "Album",
	    price: "11",
	    quantity: "1",
    },
    ],
    currency: "USD",
    order: "390",
    redirectUrl: "",
    }),
};
```

**Response** -

```
{
    "ok":true,
    "result":{"url":"[https://dev.rocketdemo.net/hostedPage
    /f7cb4141-3030-4245-8aa1-](https://dev.rocketdemo.net/hostedP
    age/f7cb4141-3030-4245-8aa1-)[f5cf95b5d504](https://dev.rocke
    tdemo.net/hostedPage/f7cb4141-3030-4245-8aa1-f5cf95b5d504)"}

}
```

3\. Once Merchant received the response as a True, then send the UUID as the response to the Merchant site.

***On click of \[Pay for your order with RocketFuel] paste below Code Snippet.***

**Code Snippet--**

```
const request=require('request');
var options = {

    method: "POST",
    url: process.env.API_ENDPOINT + "auth/login",
    headers: {
    "Content-Type": "application/json",
    },
    body: JSON.stringify({
	    email: process.env.MERCHANT_EMAIL,
	    password: process.env.MERCHANT_PASS,
    }),
};

request(options, function (error, response) {

    if (error) throw new Error(error);    
    let accessToken = JSON.parse(response.body).result.access;

    //place the order API Call
    var options = {
	    method: "POST",
	    url: process.env.API_ENDPOINT + "hosted-page",
	    headers: {
		    authorization: "Bearer " + accessToken,
		    "Content-Type": "application/const" 
		    } 
	    },
	    body: JSON.stringify({
	    amount: "11.00",
	    merchant_id: process.env.MERCHANT_ID,
	    cart: [
	    {
		    id: "23",
		    name: "Album",
		    price: "11",
		    quantity: "1",
		   },
	   ],
	    currency: "USD",
	    order: "390",
	    redirectUrl: "",
}),
};

request(options, function (error, response) {

    if (error) throw new Error(error);
    let resp = JSON.parse(response.body);
    if(resp.result !== undefined && resp.result.url !==undefined){
		let  urlArr = resp.result.url.split("/");
		let  uuid = urlArr[urlArr.length - 1];
		res.status(200).send({ uuid:  uuid });
	}else{
		res.status(400).send({ error:  "Failed to place order" });
		}
	 });
});
```

## Javascript Library

4. **RKFL JS** [**CDN**](https://d3rpjm0wf8u2co.cloudfront.net/static/rkfl.js) **and Implementation**

   4.1. Add the script from [**CDN**](https://d3rpjm0wf8u2co.cloudfront.net/static/rkfl.js) to the Merchant site.

   4.2 Once we get the response with the uuid. We will initialise an object of the above included script, while initialising the object we will pass following :-

   * uuid
   * callback function
   * environment
   * Token

     ```
     const  uuidInfo = JSON.parse(result);
     if(uuidInfo.error !== undefined){
     	alert("Order placement failed");
     	return  false;
     }
     uuid = uuidInfo.uuid;
     rkfl = new  RocketFuel({
     	uuid,
     	callback:  callBackFunc,
     	environment:  "<%= developmentEnv %>"  // prod, preprod
     });
     ```

4.3. After initialising the object start the payment by calling the initPayment method of the above script.

```
	function  startPayment(){
		rkfl.initPayment();
	}
```

4.4. Callback payload

```
 // In case of Bank/Exchange payment
	      {
            paymentMode: 'Bank/Exchange',
            txn_id: 
            status: 
            meta:
          },

		  Sample response:
		  {
            paymentMode: 'Bank/Exchange',
            txn_id: "7df55d22-fa5e-4ca2-9af4-a39c95f18b3a"
            status: 0
            meta: {offerId: "1630402767550"}
          },
	 


// In case of Wallet payment
      {
        paymentMode: 'Wallet',
        status: 
        recievedAmount:
        currency:
      },

       Sample response:
	   {
		   paymentMode: 'Wallet',
		   status:"completed",
		   recievedAmount:10.00,
		   currency:"ETH"
	   }
```

### You can refer to the [REFERENCE\_LINK](https://github.com/RocketFuel-BlockChain-Inc/rocketfuel-readme/tree/master) for demonstration.


---

# 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://docs.rocketfuel.inc/developer-guides/api-reference/payins/rocketfuel-ui-integration/generate-invoice-link.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.
