Code Monkey home page Code Monkey logo

payment-hub's Introduction

payment-hub

Repository to house the payment hub for integration with external payment schemas like Mojaloop, GSMA and MTN Uganda.

Payment Hub is the component, which connects DFSPs to switches. In our case, it connects Fineract CN to Mojaloop, and Fineract v1.2 to Mojaloop. The Payment Hub communicates with the Fineract versions via REST API. To support the calls and actions, both Fineract versions had to be upgraded.

Build

Put a settings.xml into your ~/.m2 directory with the following content:

<?xml version="1.0" encoding="UTF-8"?>
<settings xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd" xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <servers>
      <server>
      <username>mb-gatesprojects</username>
      <password>ModusBox</password>
      <id>modusbox-release-local</id>
    </server>
  </servers>
  <profiles>
    <profile>
      <repositories>
        <repository>
          <id>central</id>
          <name>Central Repository</name>
          <url>http://repo.maven.apache.org/maven2</url>
          <layout>default</layout>
          <snapshots><enabled>false</enabled></snapshots>
        </repository>
        <repository>
          <snapshots><enabled>false</enabled></snapshots>
          <id>modusbox-release-local</id>
          <name>libs-release</name>
          <url>https://modusbox.jfrog.io/modusbox/libs-release</url>
        </repository>
      </repositories>
      <pluginRepositories>
        <pluginRepository>
          <id>central</id>
          <name>Central Repository</name>
          <url>http://repo.maven.apache.org/maven2</url>
          <layout>default</layout>
          <snapshots><enabled>false</enabled></snapshots>
          <releases><updatePolicy>never</updatePolicy></releases>
        </pluginRepository>
        <pluginRepository>
          <snapshots><enabled>false</enabled></snapshots>
          <id>modusbox-plugin-release</id>
          <name>plugins-release</name>
          <url>https://modusbox.jfrog.io/modusbox/plugins-release</url>
        </pluginRepository>
      </pluginRepositories>
      <id>artifactory</id>
    </profile>
  </profiles>
  <activeProfiles>
    <activeProfile>artifactory</activeProfile>
  </activeProfiles>
</settings>

Navigate to the sources folder in the payment-hub project and run the following:

mvn clean package

Deploy

Copy the paymenthub/sources/payment-hub/target/payment-hub-1.0.0-SNAPSHOT.jar file to your working directory.

Copy the application.yml file from work folder to the same working directory, and update its config. It is not included in the build jar file, to make it easily editable.

FSP - Fineract 1.X settings

fsp-settings:
  ilp-secret: h4on38bsDjKiat2783gnklgafikmeuu5123kpobb7jm99
  auth:
    profile: BASIC # NONE, BASIC, BASIC_TWOFACTOR, OAUTH, OAUTH_TWOFACTOR
    encode: NONE # NONE, BASE64
    login-class: hu.dpc.rt.psp.dto.fsp.LoginFineractXResponseDTO
  headers:
  - name: user
    key: User
  - name: tenant
    key: Fineract-Platform-TenantId
  operations: #hub -> fsp
  - name: operation-basic-settings
    user: mifos
    password: password
    host: http://localhost
    port: 8080
  - name: auth #login
    base: fineract-provider/api/v1/authentication
  - name: requests
    base: fineract-provider/api/v1/interoperation/requests
  - name: parties
    base: fineract-provider/api/v1/interoperation/parties
  - name: quotes
    base: fineract-provider/api/v1/interoperation/quotes
  - name: transfers
    base: fineract-provider/api/v1/interoperation/transfers

FSP - Fineract CN settings

fsp-settings:
  ilp-secret: llklokklsllakkskksnnqweq6665446a6sd4asdlkjaf
  auth:
    profile: OAUTH # NONE, BASIC, BASIC_TWOFACTOR, OAUTH, OAUTH_TWOFACTOR
    encode: BASE64 # NONE, BASE64
    login-class: hu.dpc.rt.psp.dto.fsp.LoginFineractCnResponseDTO
  headers:
  - name: user
    key: User
  - name: tenant
    key: X-Tenant-Identifier
  operations: #hub -> fsp
  - name: operation-basic-settings
    user: interopUser
    password: intop@d1
    host: http://payments.dpc.hu
    port: 80 #2034
  - name: auth #login
    port: 80 #2021
    base: /identity/v1/token
  - name: requests
    base: /interoperation/v1/transactions
  - name: parties
    base: /interoperation/v1/parties
  - name: quotes
    base: /interoperation/v1/quotes
  - name: transfers
    base: /interoperation/v1/transfers

OTT - GSMA Settings

ott-settings:
  cors-enabled: true
  apikey: u8YfSQNnNsGFAaqRm3sGShpO2ywLRJgs
  operations: #hub -> ott
  - name: operation-basic-settings
    host: https://sandbox.mobilemoneyapi.io/simulator/v1.0/mm
    tenants:
    - name: tn03
      port: 48888
    - name: tn04
      port: 48889
  - name: transactions
    base: transactions
  - name: accounts
    base: accounts
  bindings: #ott -> hub
  - name: binding-basic-settings
    host: http://0.0.0.0
    port: 58080
  - name: merchantpayment # post merchant payment
    base: merchantpayment
  - name: transfer # post peer-to-peer transfer
    base: transfer

Currently, the basic transaction use cases - Merchant Payment and Peer-To-Peer transfer - have been integrated with the Payment Hub.

payment-hub's People

Contributors

avikganguly01 avatar conradsp avatar dial-registry avatar edcable avatar fynmanoj avatar marta-jankovics avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

payment-hub's Issues

Null pointer exception and program crash when configuration values are not given in the yml file

Summary:

If application.yml is not in resource directory or if the values are empty the program crashes with null pointer exception.

Steps to reproduce:

Remove any values from the fsp-settings: auth in the application.yml and run the program

Expected behaviour:

The program should warn about the empty value.

Observed behaviour:

Program Crash

Screenshots:



 
22:31:13.396 DEBUG [main] org.springframework.boot.diagnostics.FailureAnalyzers - FailureAnalyzer org.springframework.boot.autoconfigure.jdbc.HikariDriverConfigurationFailureAnalyzer@587c5c1 failed
java.lang.TypeNotPresentException: Type org.springframework.jdbc.CannotGetJdbcConnectionException not present
    at sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:117) ~[?:1.8.0_121]
    at sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:125) ~[?:1.8.0_121]
    at sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49) ~[?:1.8.0_121]
    at sun.reflect.generics.visitor.Reifier.reifyTypeArguments(Reifier.java:68) ~[?:1.8.0_121]
    at sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:138) ~[?:1.8.0_121]
    at sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49) ~[?:1.8.0_121]
    at sun.reflect.generics.repository.ClassRepository.getSuperclass(ClassRepository.java:90) ~[?:1.8.0_121]
    at java.lang.Class.getGenericSuperclass(Class.java:777) ~[?:1.8.0_121]
    at org.springframework.core.ResolvableType.getSuperType(ResolvableType.java:466) ~[spring-core-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.core.ResolvableType.as(ResolvableType.java:455) ~[spring-core-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.core.ResolvableType.forClass(ResolvableType.java:1037) ~[spring-core-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.boot.diagnostics.AbstractFailureAnalyzer.getCauseType(AbstractFailureAnalyzer.java:58) ~[spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
    at org.springframework.boot.diagnostics.AbstractFailureAnalyzer.analyze(AbstractFailureAnalyzer.java:34) ~[spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
    at org.springframework.boot.diagnostics.FailureAnalyzers.analyze(FailureAnalyzers.java:114) [spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
    at org.springframework.boot.diagnostics.FailureAnalyzers.reportException(FailureAnalyzers.java:107) [spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
    at org.springframework.boot.SpringApplication.reportFailure(SpringApplication.java:848) [spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
    at org.springframework.boot.SpringApplication.handleRunFailure(SpringApplication.java:832) [spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) [spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) [spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) [spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
    at hu.dpc.rt.psp.PaymentHubApplication.main(PaymentHubApplication.java:31) [classes/:?]
Caused by: java.lang.ClassNotFoundException: org.springframework.jdbc.CannotGetJdbcConnectionException
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[?:1.8.0_121]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[?:1.8.0_121]
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) ~[?:1.8.0_121]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[?:1.8.0_121]
    at java.lang.Class.forName0(Native Method) ~[?:1.8.0_121]
    at java.lang.Class.forName(Class.java:348) ~[?:1.8.0_121]
    at sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:114) ~[?:1.8.0_121]
    ... 20 more
22:31:13.404 ERROR [main] org.springframework.boot.SpringApplication - Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'fspRestClient': Invocation of init method failed; nested exception is java.lang.NullPointerException
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:139) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:419) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1737) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:576) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:846) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:863) ~[spring-context-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546) ~[spring-context-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) [spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) [spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) [spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) [spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE]
    at hu.dpc.rt.psp.PaymentHubApplication.main(PaymentHubApplication.java:31) [classes/:?]
Caused by: java.lang.NullPointerException
    at hu.dpc.rt.psp.component.FspRestClient.lambda$postConstruct$0(FspRestClient.java:70) ~[classes/:?]
    at java.util.ArrayList.forEach(ArrayList.java:1249) ~[?:1.8.0_121]
    at hu.dpc.rt.psp.component.FspRestClient.postConstruct(FspRestClient.java:66) ~[classes/:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_121]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_121]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_121]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_121]
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:363) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:307) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:136) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]
    ... 17 more
Disconnected from the target VM, address: '127.0.0.1:45335', transport: 'socket'
 
Process finished with exit code 1


Add Capability to efficiently interface with external fraud monitoring system

DFSP could implement a separate fraud monitoring system which could be invoked by the Payment Hub as part of the outgoing or incoming payment flow.
DFSP side fraud monitoring could utilize much more information about the customer, compared to simply monitoring the flow of transactions, such as: A priori knowledge of customer’s accounts, typical transaction mix, channels, geolocations, devices used, rate of typing.
Transactions can be:

  • Stopped - in case of scoring high by the fraud monitoring system
  • Paused - contacting the customer for validation on other channel and resume the transaction later
  • Let it go through
  • Fraud monitoring does not alert on the given transaction
  • Fraud monitoring subsystem is not responding in the given timeframe

Harden Architecture & Design for High Availability, Fault Tolerance

The Payment Hub should provide adequately high availability at the DFSP. This depends on environment, availability of the overall environment (dual data centers, network redundancy), customer expectations and regulatory requirements.
The Payment Hub should be able to receive transactions, even in the case the Account Management System (AMS) is not available on behalf of the DFSP.
To fulfill these requirements and reduce overall cost, in a modern architecture, software based replication, clustering, coordination services can be utilized, although easy installation and operation should not be compromised. This will require the necessary enhancements in the Payment Hub.

Integrate with DPC Simulator

Easy to use, simple to setup test environment for development, testing for DFSPs and their developers.
Could be used for UAT testing by the DFSPs.
Requires a single computer to run all the components to enable:

  • Functional testing
  • Happy scenarios
  • Modelling failure scenarios by artificially injecting delays, error cases
  • Performance testing

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.