Blog Infos
Author
Published
Topics
Published

In this article, I will explain how to integrate CCAvenue Payment integration in Android and the backend using node.js.

Note: you need to have a CCAvenue account created with your domain/ip whitelisted to make transactions in production and testing environment.

You have to register your business on ccAvenue after successful registration you will get workingKeyaccessCode, and merchantId.

Prerequisite: You should have some experience in node.js

Now, we will code our backend in Node.js

So, the dependency I am using is here.

"body-parser": "^1.20.2",
"cors": "^2.8.5",
"crypto-js": "^4.1.1",
"dotenv": "^16.3.1",
"express": "^4.18.2",
"node-ccavenue": "^1.0.5"

the main dependency used is node-ccavenue this package will help us to call ccAvenue servers to make payments.

so, In the index.js file copy this

var express = require("express");
var app = express();
var cors = require("cors");
const dotenv = require("dotenv");
const bodyParser = require("body-parser");

app.use(cors());
app.use(express.json());
dotenv.config();

const paymentRouter = require("./routes/payment.routes");

app.get("/", function (req, res) {
  res.send("CCavenu server!!");
});

app.use("/api", bodyParser.urlencoded(), paymentRouter);

var server = app.listen(3000, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log("Example app listening at http://localhost:3000", host, port);
});

Here what I have done is started a server on 3000 port and created a path /api.

now the paymentRouter has 2 POST APIs /request/phone and /response

var express = require("express");
var paymentController = require("../controllers/payment.controller");
var paymentRouter = express.Router();

paymentRouter.post(
  "/request/phone",
  paymentController.handlePaymentControllerPhone
);
paymentRouter.post(
  "/response",
  paymentController.handleResponsePaymentController
);

module.exports = paymentRouter;

this is the payment.routes.js file

So, the /request/phone will be called by the client app to get the payment link which we will use in the webview to make payment.

/response POST call will be called by ccAvenue servers to send the payment success or failure status. Once ccAvenue sends payload based on status we we will redirect to success or failure pages created.

So, now we will have to write code for handling request to get payment links. so the mobile app will send details about order_id, and amount to this POST call and this will return the payment link. You can also pass access_code and working_key from the client to the server to create an encrypted value.

static async handlePaymentControllerPhone(req, res, next) {
    try {
      const ccav = new nodeCCAvenue.Configure({
        ...req.body.keys,
        merchant_id: "MERCHANT_ID",
      });
      const orderParams = {
        redirect_url: encodeURIComponent(
          `https://DOMAIN/api/response?access_code=${req.body.keys?.access_code}&working_key=${req.body.keys?.working_key}`
        ),
        cancel_url: encodeURIComponent(
          `https://DOMAIN/api/response?access_code=${req.body.keys?.access_code}&working_key=${req.body.keys?.working_key}`
        ),
        billing_name: "Name of the customer",
        currency: "INR",
        ...req.body.orderParams,
      };
      const encryptedOrderData = ccav.getEncryptedOrder(orderParams);
      res.setHeader("content-type", "application/json");
      res.status(200).json({
        payLink: `https://secure.ccavenue.com/transaction/transaction.do?command=initiateTransaction&access_code=${req.body.keys.access_code}&encRequest=${encryptedOrderData}`,
      });
    } catch (err) {
      next(err);
    }
}

So I will send back the ccAvenue link to show it in webview.

the URL sending should be in the correct format mentioned by ccAvenue.

Now, we will also write code for handling response sent by ccAvenue servers after payment failure or success.

static async handleResponsePaymentController(req, res, next) {
    try {
      var encryption = req.body.encResp;
      const ccav = new nodeCCAvenue.Configure({
        ...req.query,
        merchant_id: "MERCHANT_ID",
      });
      var ccavResponse = ccav.redirectResponseToJson(encryption);
      var ciphertext = CryptoJS.AES.encrypt(
        JSON.stringify(ccavResponse),
        "Astro"
      ).toString();
      if (ccavResponse["order_status"] == "Success") {
        res.redirect(
          `https://DOMAIN/transaction?type=success&val=${ciphertext}`
        );
      } else {
        res.redirect(
          `https://DOMAIN/transaction?val=${ciphertext}`
        );
      }
    } catch (error) {
      next(error);
    }
  }

this is simple based on order_status I will redirect the user to my success page or failure page.

Now, you have to run the server locally by running this command

npm start

Now, if you hit the API from your POSTMAN

you should get the response. if you run this cURL

curl --location 'http://localhost:3000/api/request/phone' \
--header 'Content-Type: application/json' \
--data '{
        "orderParams": {
          "order_id": 1694784153561_12344",
          "amount": 100,
          "language": "en"
        },
        "keys": {
          "working_key": "WORKING_KEY",
          "access_code": "ACCESS_CODE"
        }
}'
{
    "payLink": "https://secure.ccavenue.com/transaction/transaction.do?command=initiateTransaction&access_code=ACCESS_CODE&encRequest=d7XXXXXXXXXXX7161XXXXXXXXXXXXXXXXX0a9ca963XXXXXXXXXXXXcb94ffc25a666XXXXX"
}

So, Now let’s integrate payments into the Mobile App.

Now, create an Android project.

Step 1: You need to make the POST call to the local host server.

I am using retrofit to make HTTP calls.

implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation "com.squareup.retrofit2:converter-gson:2.9.0"

Job Offers

Job Offers

There are currently no vacancies.

OUR VIDEO RECOMMENDATION

,

Mastering IoT-Flutter Integration: A Journey Through DiY Smart Device Case Studies

In this engaging session, we will explore the exciting world of Do-It-Yourself (DIY) Internet of Things (IoT) projects and various integration ways with Flutter.
Watch Video

Mastering IoT-Flutter Integration: A Journey Through DiY Smart Device Case Studies

Alex Bordei
Flutter Developer
Whiz Center

Mastering IoT-Flutter Integration: A Journey Through DiY Smart Device Case Studies

Alex Bordei
Flutter Developer
Whiz Center

Mastering IoT-Flutter Integration: A Journey Through DiY Smart Device Case Studies

Alex Bordei
Flutter Developer
Whiz Center

Jobs

Now, create ApiService.kt where you will create a method to make Post Request.

interface ApiService {

    @Headers("Content-Type: application/json")
    @POST("api/request/phone")
    suspend fun sendPhoneRequest(@Body request: RequestBody): ApiResponse 
}

You need to have data models of input and output.

data class RequestBody(
    val orderParams: OrderParams,
    val keys: Keys
)

data class OrderParams(
    val order_id: String,
    val amount: Int,
    val language: String
)

data class Keys(
    val working_key: String,
    val access_code: String
)

data class ApiResponse(
    val payLink: String
)

Step 2: Now, create ApiClient.kt where you define the configuration to make HTTP calls.

object ApiClient {
    private const val BASE_URL = "http://10.0.2.2:3000/"

    private val retrofit: Retrofit = Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .build()

    val apiService: ApiService = retrofit.create(ApiService::class.java)
}

Here I am using localhost and to test on the emulator you need to mention the above BASE_URL.

To make HTTP call you need to define the network_security_config file
you don’t need in the case of https

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
            <certificates src="user" />
        </trust-anchors>
    </base-config>
</network-security-config>

and put this in res->xml

now in AndroidManifest.xml

under the application tag put this in its config

android:networkSecurityConfig="@xml/network_security_config"

and make sure you have added this permission

<uses-permission android:name="android.permission.INTERNET" />

Step 3: Now you need to create a suspend method to call this POST request from your composable.

class Repo {

    companion object{
        suspend fun sendPhoneRequest(request: RequestBody): ApiResponse {
            val apiService = ApiClient.apiService
            return withContext(Dispatchers.IO) {
                apiService.sendPhoneRequest(request)
            }
        }
    }
}

Step 4: Now, the last step is to show in UI.

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            PaymentAppTheme {
             
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    MainView()
                }
            }
        }
    }
}

@Composable
fun MainView() {
    var paylink by remember { mutableStateOf("") }

    val coroutineScope = rememberCoroutineScope()
    
    if(paylink.isNotEmpty()){
        WebViewScreen(url = paylink)
    }
    else{
        val requestBody = RequestBody(
            orderParams = OrderParams(
                order_id = "1694784153561_12344",
                amount = 1,
                language = "en"
            ),
            keys = Keys(
                working_key = "working_key",
                access_code = "access_code"
            )
        )

        Column(
            modifier = Modifier.fillMaxSize(),
            verticalArrangement = Arrangement.Center, 
            horizontalAlignment = Alignment.CenterHorizontally 
        ) {
            BasicTextField(
                value = TextFieldValue(text = "Click to Send Request"),
                
                modifier = Modifier.padding(16.dp)
            )
            Button(
                onClick = {
                    coroutineScope.launch {
                        val result = sendPhoneRequest(requestBody)
                        
                        paylink = result.payLink
                    }
                }
            ) {
                Text("Send Request")
            }
        }
    }

    
}

@Composable
fun WebViewScreen(url: String) {
    var webView: WebView? by remember { mutableStateOf(null) }

    LaunchedEffect(url) {
        webView?.loadUrl(url)
    }

    AndroidView(
        modifier = Modifier.fillMaxSize(),
        factory = { context ->
            WebView(context).apply {
                webView = this
                settings.javaScriptEnabled = true
                webViewClient = WebViewClient()
            }
        }
    )
}

So, it is simple now with the click of the button Send Request I am fetching the payment link and once I get the string I show load the URL in Webview.

In this article, I will explain how to integrate CCAvenue Payment integration in Android and the backend using node.js.

Thank You for reading this article.

 

This article was previously published on proandroiddev.com

YOU MAY BE INTERESTED IN

YOU MAY BE INTERESTED IN

blog
It’s one of the common UX across apps to provide swipe to dismiss so…
READ MORE
blog
In this part of our series on introducing Jetpack Compose into an existing project,…
READ MORE
blog
This is the second article in an article series that will discuss the dependency…
READ MORE
blog
Let’s suppose that for some reason we are interested in doing some tests with…
READ MORE

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.

Menu