Sample Application

In this section we show you how to write an Application on OPC using a variety of Identity, Instrument and Transaction Paylets. In the proposed Application we will show how to create instances of the required Paylets (Managed Account, External Account etc. ), deposit funds into a Programme, create a Virtual Card and subsequently transfer the deposited funds onto the created Virtual Card. Finally, we simulate a Purchase on the Virtual Card.

Sample Application

Connecting to the APIs

Code Generation to connect to the API

If you're using Java, we have a Maven project containing the generated client code that you can depend on to get you started more quickly. Simply add the following dependency to your project:

<dependency>
    <groupId>com.ixaris.ope</groupId>
    <artifactId>ope-applications-java-client</artifactId>
    <version>0.9.0</version>
</dependency>

Or, if you're using Javascript, you can depend on this NPM package.

For other languages, please use Swagger Codegen by downloading the built JAR file from Maven, and executing the JAR file as follows:

$ java -jar swagger-codegen-cli-2.2.2.jar generate -i https://app-gateway.{{ book.opcDomain }}/swagger-docs/swagger.yaml -l <language> -o <path_to_output>

This should generate the API client bindings in the specified language in the requested output directory.

API Client Setup

The generated client code is split into a number of classes, each representing a separate resource on the OPC APIs. You can use the respective API by initializing it with an ApiClient (which acts as a configuration object) as follows:

// Use the default configuration to initialize a client for the Auth API Resource
final AuthApi authApi = new AuthApi(new ApiClient());

Login

To login, you need to perform a POST request on the /auth/login path.

The following headers need to be supplied:

  • X-callref - A unique call reference you generate to track API calls. Make sure you use a different reference every time since repeated requests will only be processed once
  • X-programmeKey - See What is my ProgrammeKey? section in FAQs

Additionally, the request body needs to contain the following information. Make sure you replace these with your own details:

{
  "programmeId": "3749203750",  // ID of Programme
  "credentialCode": "username", // the username with which you signed up
  "password": "password"  // the password which you used to sign up
}

This should return a response containing an authorisation token, as follows:

{
  "token": "5749465942632969"
}

Once you’re logged in, you can use this token to perform authenticated calls, by passing the token as the Authorization header.

Alternatively, through Java, this process can be done as follows:

// Login with your credentials to get an auth token
final LoginParams loginRequest = new LoginParams()
  .credentialCode(USERNAME)
  .password(PASSWORD)
  .programmeId(PROGRAMME_ID);

final LoginResult loginResult = authApi.authLogin(
  generateCallRef(),
  PROGRAMME_KEY,
  loginRequest);
// get PROGRAMME_KEY from your ‘Getting Started’ doc
// The authorisation token is in the login result
final String token = loginResult.getToken();

Create a Managed Account

Once we have an Authorisation Token, you can start using the APIs. Let's start by creating an instance of a Managed Account. An instance of a Managed Account can be created by calling POST on the /managed_accounts/_/create URL, with the following request:

{
  "profileId": "57258742353", // ID of profile defining configuration of the Managed Account
  "ownerId": "14269340583", // ID of the pre-created Corporate Identity Instance
  "friendlyName": "John's Managed Account",
  "currency": "GBP",
  "issuingProvider": "Issuer"
}

Alternatively, through Java this is how it is done:

final ManagedAccountsApi managedAccountsApi = new ManagedAccountsApi(client);
final CreateManagedAccountParams createManagedAccountParams =
  new CreateManagedAccountParams()
    .profileId(managedAccountProfileId)
    .ownerId(managedAccountOwnerId)
    .friendlyName("John's Managed Account")
    .currency("GBP")
    .issuingProvider("Issuer");

// Create a managed account
api.managedAccountsIdCreate(
  generateCallRef(),
  PROGRAMME_KEY,
  token,
  createManagedAccountParams);

Create an External Bank Account

The Managed Account described above will hold corporate funds as deposited externally from a bank account (via bank transfer). This can be done by calling POST on the /external_accounts/_/create. Here's an example request:

{
  "profileId": "12345", // ID of profile defining configuration of the External Bank Account
  "ownerId": "45678", // ID of the pre-created Corporate Identity Instance
  "friendlyName": "John's External Account",
  "externalAccountInfo": {
    "bankAccountNumber": "31926819",
    "payee": "Mr John Doe",
    "bankName": "Bank of England",
    "bankCode": "NWBK",
    "branchCode": "601613",
    "accountType": "Savings",
    "checkDigits": "29",
    "ibanCode": "GB29NWBK60161331926819",
    "swiftCode": "ABCDEF12",
    "branchAddress": "Bank of England, London, UK",
    "country": "GB",
    "additionalInformation": "Any additional information goes here",
    "currency": "GBP"
  }
}

Alternatively through Java:

final ExternalAccountsApi externalAccountsApi = new ExternalAccountsApi(client);
final CreateExternalAccountParams createExternalAccountRequest =
  new CreateExternalAccountParams()
    .profileId(externalAccountProfileId)
    .ownerId(externalAccountOwnerId)
    .friendlyName("John's External Account")
    .externalAccountInfo(new ExternalAccountInfo()
      .bankAccountNumber("31926819")
      .payee("Mr John Doe")
      .bankName("Bank of England")
      .bankCode("NWBK")
      .branchCode("601613")
      .accountType("Savings")
      .checkDigits("29")
      .ibanCode("GB29NWBK60161331926819")
      .swiftCode("ABCDEF12")
      .branchAddress("Bank of England, London, UK")
      .country("GB")
      .additionalInformation("Any additional information goes here")
      .currency("GBP"));

// Create an external account
externalAccountsApi.externalAccountsIdCreate(
  generateCallRef(),
  PROGRAMME_KEY, 
  token, // authentication token, as generated during authentication
  createExternalAccountRequest);

Deposit funds from External Bank Account to Managed Account

Now that we have created the instances representing the internal Managed Account and the External Bank Account, we can simulate a transfer of funds across the two. In a real-life Application, the way this would happen is that the corporate user executes a Payin transaction – on the Application. This returns a unique identifier (and destination bank account details) that is then quoted when the user is doing the bank transfer from his bank’s portal.

During development, we simulate this process through a two-step process:

  1. First, we simulate the ‘availability’ of funds in the external bank account. As you appreciate this is not applicable on a production system
  2. Second, we execute the actual deposit transaction (the one which we would have executed in a real-life scenario).

To simulate availability of funds in an external bank account perform a POST request on /payin_simulator/_/payin. Here's a typical request:

{
  "amount": {
    "currency": "GBP",
    "amount": "10000"
  },
  "externalAccountId": "15616498849", // this is the ID of the External Account instance (as created in section above)
  "additionalInfo": "Any additional information goes here"
}

Upon completion, there will be enough funds in the External Bank Account instance to allow for a deposit to be done. This is done through a POST request on /deposits/_/create_from_external_account, using the following request body:

{
  "profileId": "12345", // ID of profile defining configuration of the Deposit transaction
  "amount": {
    "currency": "GBP",
    "amount": "10000"
  },
  "sourceInstrumentId": {
    "type": "external_accounts", // type of the source instrument
    "id": "4567891802" // this is the ID of the External Bank Account instance (as created before)
  },
  "sourcePayinId": "12345",
  "destinationInstrumentId": {
    "type": "managed_accounts", // type of the destination instrument
    "id": "5489468489" // this is the ID of the Managed Account instance (as created before)
  }
}

Alternatively through Java:

final PayinSimulatorApi payinSimulatorApi = new PayinSimulatorApi(client);
final CurrencyAmountMessage payinAmount = new CurrencyAmountMessage().currency("GBP").amount(10000L);
final CreatePayinSimulationParams payinRequest = new CreatePayinSimulationParams()
  .amount(payinAmount)
  .externalAccountId(externalAccountId)
  .additionalInfo("Any additional information goes here");

// Simulate a payin
final PayinSimulation payin = payinSimulatorApi.payinSimulatorIdPayin(
  generateCallRef(),
  PROGRAMME_KEY,
  token,
  payinRequest);

final DepositsApi depositsApi = new DepositsApi(client);
final CreateExternalAccountDepositParams depositRequest = new CreateExternalAccountDepositParams()
  .profileId(depositProfileId)
  .amount(payinAmount)
  .sourceInstrumentId(new TypedId().type("external_accounts").id(externalAccountId))
  .sourcePayinId(payin.getId())
  .destinationInstrumentId(new TypedId().type("managed_accounts").id(managedAccountId));

// Perform the deposit
depositsApi.depositsIdCreateFromExternalAccount(
  generateCallRef(),
  PROGRAMME_KEY,
  token, // authentication token
  depositRequest);

Create a Virtual Card

Now that we have funds deposited in the Managed Account, we can create Virtual Cards (also referred to as Managed Cards), which will be used for online purchases. Creating a Virtual Card can be done by calling POST on /managed_cards/_/create. Here's a sample request:

{
  "profileId": "5743105732", // ID of profile defining configuration of the Managed Card
  "ownerId": "2483290572", // ID of the Corporate Identity Instance
  "friendlyName": "John's GBP card",
  "currency": "GBP",
  "issuingProvider": "IssuingProvider",
  "processingProvider": "ProcessingProvider",
  "nameOnCard": "John Doe"
}

The next step is to transfer funds onto the created Virtual Card. This can be done using the Transfer transaction, by calling POST on /transfers/_/create. In this example we also apply a flat fee of GBP1 from the Managed Account when doing this operation – this can be a fee that you as the Developer or the Programme Manager charge the client for using your Application. Here's how this request would look like:

{
  "profileId": "984239502", // ID of profile defining configuration of the Deposit transaction
  "amount": {
    "currency": "GBP",
    "amount": "5000"
  },
  "sourceInstrumentId": {
    "type": "managed_accounts",
    "id": "5489468489" // this is the ID of the Managed Account instance (as created before)
  },
  "destinationInstrumentId": {
    "type": "managed_cards",
    "id": "6538493025" // this is the ID of the Managed Card instance (as created before)
  },
  "fees": [{
    "instrumentId": {
      "type": "managed_accounts",
      "id": "5489468489" //this is the ID of the Managed Account instance (as created before) from where fee will be taken
    },
    "feeDefinition": {
      "key": "exampleFee",
      "feeType": "FLAT",
      "flatAmountFees": [{
        "currency": "GBP",
        "amount": "100" //pence - the lowest denomination of the currency
      }]
    }
  }]
}

When using the Java client code, this would look like this:

final ManagedCardsApi managedCardsApi = new ManagedCardsApi(client);
final CreateManagedCardParams createCardRequest = new CreateManagedCardParams()
  .profileId(cardProfileId)
  .ownerId(cardOwnerId)
  .friendlyName("John's GBP card")
  .currency("GBP")
  .issuingProvider("IssuingProvider")
  .processingProvider("ProcessingProvider")
  .nameOnCard("John Doe");

// Create the card
final ManagedCard card = managedCardsApi.managedCardsIdCreate(
  generateCallRef(),
  PROGRAMME_KEY,
  token,
  createCardRequest);

final TransfersApi transfersApi = new TransfersApi(client);
final TypedId sourceInstrumentId = new TypedId().type(MANAGED_ACCOUNT_TYPE).id(managedAccountId);
final CreateTransferParams createTransferParams =
  new CreateTransferParams().profileId(transferProfileId)
    .amount(new CurrencyAmountMessage().currency("GBP").amount(1000L)) // 10.00 GBP
    .sourceInstrumentId(sourceInstrumentId)
    .destinationInstrumentId(new TypedId().type(MANAGED_CARD_TYPE).id(card.getId()))
    .addFeesItem(new Fee().instrumentId(sourceInstrumentId)
      .feeDefinition(new FeeDefinition().key("exampleFee")
        .feeType(FeeTypeEnum.FLAT)
        .addFlatAmountFeesItem(new CurrencyAmountMessage().currency("GBP").amount(100L))));   // 1 GBP

// Perform the transfer
transfersApi.transfersIdCreate(generateCallRef(), PROGRAMME_KEY, token, createTransferParams);

Simulate a purchase on the card

Once the card is loaded with funds, it can now be used like any other card for purchases. On production, such process takes place outside of the scope of OPC. OPC however provides a way to simulate a purchase by calling POST on /card_issuing_simulator/purchase.

{
  "cardId": "6538493025", //this is the ID of the Managed Card Instance (as created before)
  "purchaseAmount": {
    "currency": "GBP",
    "amount": "-4500"
  },
  "merchantName": "Example Merchant"
}

In Java:

final CardIssuingSimulatorApi cardIssuingSimulatorApi = new CardIssuingSimulatorApi(client);
final PurchaseSimulationParams purchaseRequest = new PurchaseSimulationParams()
  .cardId(managedCardId)
  .purchaseAmount(new CurrencyAmountMessage().currency("GBP").amount(-4500L)) // 45.00 GBP
  .merchantName("Example Merchant");

// Simulate a purchase
cardIssuingSimulatorApi.cardIssuingSimulatorPurchase(
  generateCallRef(),
  PROGRAMME_KEY,
  token,
  purchaseRequest);

This will reduce the balance(s) of the card by the specified amount, and generates a corresponding transaction entry – this transaction entry can be seen on the statement, available through API or visible from the Sandbox portal.


The example above covers some of the more important APIs related to instrument creation and fund movements. These APIs are all available for you to use in your Application - for more information about the APIs, refer to the Swagger documentation or our API reference.