# API specs of Service Providers

This page describes API specs that Service Providers need to expose to interact with serviceX.

# Overview

The following information needs to be provided by a Service Provider to Credify for Service Provider integration.

  • [Required] OIDC setup URL
    • The URL required to kick off OpenID Connect with Credify. This may generate an ephemeral encryption key to securely deal with claims.
    • No authentication
  • [Required] Redirection URLs
    • The URLs that will be used once users complete OpenID Connect flow.
    • This should be receiving POST method
    • No custom authentication. It follows OIDC protocol
  • [Optional] Scope validation API
    • This endpoint validates the entire scope value based on a product specific configuration. It is optional. You may need to provide this endpoint only if you want to run validation before users send an application to consume your service.
    • For example, you want to have a new customer provide address information. This endpoint receives all the pieces of address (e.g., province, district, street) and make sure it's valid.
  • [Optional] Claim validation API
    • This endpoint validates a claim value based on a product specific configuration. It is optional. You may need to provide this endpoint only if you want to run validation before users send an application to consume your service.
    • A claim is a child of a scope. This endpoint is to validate one component of a scope value.

# Skeleton service

Integration guide

We have developed a skeleton service to minimize the integration work, which handles most common logic and SDK interaction. We provide the skeleton service in Node.js, .NET, and Java as of May 2022. All you would have to do is to clone the repository and to customize some database interaction only.

The following sections relating to the backend implementation are not necessary if you use the skeleton service.


# [Required] OIDC setup URL

Credify's OpenID Connect flow will need your little efforts to realize complete secure data transmission.

This is an API that you have to expose to other parties across Credify network. This API redirects the request to a generated URL.

# API definition

API doc for serviceX integration

# Implementation

What you have to do by yourself is

  • Configure OIDC response mode and type (authorization code flow? implicit flow?)
  • Generate a random state and keep it for validating in a callback
  • Generate a request token (JWT) to ensure the request is not tampered
  • Construct OIDC auth request URL with the request token and redirect a user to this URL
  • Node.js
  • Java
  • .NET
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const { Credify } = require("@credify/nodejs");

// You obtain these on the serviceX dashboard.
const signingPrivateKey = `-----BEGIN PRIVATE KEY-----
your private key...
-----END PRIVATE KEY-----`;
const apiKey = "YOUR_API_KEY";

const id = "YOUR_ORGANIZATION_ID";
const redirectUrl = "YOUR_REDIRECTION_URL";
const scopes = ["openid", "phone", "email", "profile"]; // depends on your config

const app = express();
app.use(bodyParser.json());
app.use(cors());

app.get("/api/oidc", async (req, res) => {
  // mode is `sandbox` or `production`
  const credify = await Credify.create(signingPrivateKey, apiKey, {
    mode: "sandbox",
  });

  // Generates a random value to identify this request afterwards.
  const state = Math.random().toString();

  // How to obtain access token through OIDC.
  const responseType = "code"; // "token"
  const responseMode = "form_post"; // "fragment"

  const options = { state, responseMode, responseType };
  if (req.query.phone_number) {
    options.phoneNumber = req.query.phone_number;
  } else if (req.query.entity_id) {
    options.userId = req.query.entity_id;
  }
  if (req.query.offer_code) {
    options.offerCode = req.query.offer_code;
  }
  if (req.query.package_code) {
    options.productCode = req.query.package_code;
  }
  if (req.query.dop_code) {
    options.productCode = req.query.dop_code;
  }

  // If you set `useEphemeralKey` true, you will see value in `privateKey`. In this case you should keep the key for decryption.
  // This `oidcUrl` contains `request token`
  const { oidcUrl, privateKey } = await credify.oidc.initiateOIDC(
    id,
    redirectUrl,
    scopes,
    options
  );

  // Store this `state`

  // Redirect a user to the OIDC URL
  res.redirect(oidcUrl);
});

In the OIDC setup URL, you need to redirect users to oidcUrl.

# [Required] Redirection URLs

As the standard of OpenID Connect, you will need to handle redirection of users. In this redirection, you will obtain an authorization code or access token upon your configuration. If you receive an authorization code, you will need to exchange it with an access token.

For the better security, we strongly recommend to have POST endpoint for redirection URL that renders frontend for users. In the backend process, it will call into getUserInfo API and handles user data securely.

Token endpoint is described here.

Once you have received the access token, you can use it to retrieve user's encrypted profile data that the user approved to share with you. The API is described here.

You will need to use the encryption private key. If you create an ephemeral private key when setting up this OIDC request, you will have to use this private key. Or else, you can use a static encryption key you can find on Dashboard.

If Service Providers provide offers, this endpoint should handle the offer redemption accordingly. By using offers, you as a Service Provider can filter out end-users that you want to reach out to. If you provide BNPL related offers, you can select users and have to onboard them to your service. In this case, the logic of this endpoint should handle onboarding if an offer code is being passed, while it should handle a normal OIDC process if it doesn't have an offer code.

OIDC callback may have the following query params

  • offer_code
    • Offer code that a user has selected, if any
  • package_code
    • Package code that a user has selected, if any
  • kyc_reference
    • KYC reference ID if Service Providers have used their own eKYC endpoint

# API definition

API doc for serviceX integration

# Implementation

What you have to do by yourself is

  • Exchange an authorization code for access token in the case when it is authorization code flow
  • Call GET userinfo API to get encrypted claim data
  • Retrieve a private key for decryption
  • Decrypt the encrypted claim data by the private key
  • Develop the frontend to handle the OIDC redirection (e.g., rendering application completed page)
  • Node.js
  • Java
  • .NET
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const { Credify } = require("@credify/nodejs");

// You obtain these on the serviceX dashboard.
const signingPrivateKey = `-----BEGIN PRIVATE KEY-----
your private key...
-----END PRIVATE KEY-----`;
const apiKey = "YOUR_API_KEY";

const id = "YOUR_ORGANIZATION_ID";
const redirectUrl = "YOUR_REDIRECTION_URL";

const app = express();
app.use(bodyParser.json());
app.use(cors());

app.post("/oidc", async (req, res) => {
  // mode is `sandbox` or `production`
  const credify = await Credify.create(signingPrivateKey, apiKey, { mode: "sandbox" });

  // Provided you send `code` and `state` you have gotten to this endpoint
  const code = req.body.code;
  const state = req.body.state;
  const accessToken = await credify.oidc.generateAccessToken(id , code, redirectUrl);

  // If you are using implicit flow, you will receive a new access token on the frontend and so you will not have to call `generateAccessToken` like above.
  // const accessToken = req.body.access_token;

  // Retrieve the ephemeral encryption private key you have created in the initial step.
  // Or you can use a static you can find on Dashboard
  const encryptionPrivateKey = ...;

  const data = await credify.oidc.userinfo(accessToken, encryptionPrivateKey);

  // Do whatever you want with the shared claims. e.g. onboarding to your service.

  // You may update the transaction status like following.
  const transactionAmount = {
    currency: "VND",
    value: 250000
  }
  await credify.offers.updateStatus(data.transaction_id, "COMPLETED", transactionAmount);

  res.json({ data });
});

And then, you just need to manage the session on your service.

# [Optional] Scope validation API

This endpoint allows Service Providers to validate the user's input on the application form of Credify context. It is similar to Claim validation API. A difference is that this endpoint will validate a set of forms. For example, if a user is providing address information, you can validate some combination between a province and a city.

It is an optional endpoint. You may implement it only when you want to validate scope values while users providing their information through serviceX.

# API definition

API doc for serviceX integration

# [Optional] Claim validation API

This endpoint allows Service Providers to validate the user's input on the application form of Credify context. It is similar to Scope validation API. A difference is that this endpoint will validate single value of a form. For example, if a user is providing an email address, you can validate its value.

It is an optional endpoint. You may implement it only when you want to validate a claim value while users providing their information through serviceX.

# API definition

API doc for serviceX integration

Last Updated: 11/18/2022, 1:10:12 AM