Skip to content

Files

Latest commit

 

History

History
205 lines (162 loc) · 6.12 KB

README_NETCETERA_GPECOM.md

File metadata and controls

205 lines (162 loc) · 6.12 KB
Global Payments logo

Netcetera 3DS SDK GP-ECOM integration

Global Payments Ecom cam be configured to use the Netcetera SDK for 3DS

Requirements

  • Netcetera 3DS sdk - in the form of an .aar android library you can get this from the Global Payments Support Team
  • API key - can be retrieved from Global Payments support team
  • acs certificate - in the form of .pem can be retrieved from Global Payments support team

Installation

  • place the .aar file in the libs directory of your app module and add it as a dependency in your app build.gradle
  implementation files("libs/3ds-sdk.aar")
  • place certificate file in the assets directory of your app

Integration

The GP Ecom calls can be done from the app.

  • instantiate the Netcetera SDK; because this is a heavy CPU operation we recommend to do it on a background thread
fun initiateNetceteraSDK(context: Context, apiKey: String) {
    ThreeDS2ServiceInstance.get().initialize(
        context,
        getThreeDS2ConfigParams(context, apiKey),
        Locale.getDefault().language,
        getThreeDS2UICustomizationMap()
    )
}


fun getThreeDS2ConfigParams(context: Context, apiKey: String): ConfigParameters {
    val assetManager = context.assets
    return ConfigurationBuilder()
        .apiKey(apiKey)
        .configureScheme(
            SchemeConfiguration.visaSchemeConfiguration()
                .encryptionPublicKeyFromAssetCertificate(assetManager, "acs.pem")
                .rootPublicKeyFromAssetCertificate(assetManager, "acs.pem")
                .build()
        )
        .build()
}

fun getThreeDS2UICustomizationMap(): Map<UiCustomizationType, UiCustomization> {
    return hashMapOf<UiCustomizationType, UiCustomization>().apply {
        put(UiCustomizationType.DEFAULT, getThreeDS2UICustomization())
        put(UiCustomizationType.DARK, getThreeDS2UICustomization())
    }
}

fun getThreeDS2UICustomization(): UiCustomization {
    return UiCustomization()
}
  • capture card data
val card = CreditCardData().apply {
    this.number = model.cardNumber
    this.expMonth = model.cardMonth.toInt()
    this.expYear = model.cardYear.toInt()
    this.cardHolderName = model.cardHolderName
    this.isCardPresent = true
}
  • add the card as a payment method, using the card data, to the customer
val addPaymentMethod = customer.addPaymentMethod(paymentId, card).create()
  • create a recurring payment method
val recurringPaymentMethod = RecurringPaymentMethod(customer.key, paymentId)
  • check if the credit card from the recurring payment method is enrolled in the 3ds process
val secureEcom = Secure3dService
    .checkEnrollment(recurringPaymentMethod)
    .withCurrency(Currency)
    .withAmount(BigDecimal(Amount))
    .withAuthenticationSource(AuthenticationSource.MobileSDK)
    .execute()
response.enrolledStatus == "ENROLLED"  
  • create a Netcetera transaction using the Netcetera SDK and the response from the previous GP call You will need to determine the card brand from the card number and map it to the DsRidValues
val netceteraTransaction = threeDS2Service.createTransaction(
    getDsRidValuesForCardNumber(card.number),
    secureEcom.acsEndVersion
)
val netceteraParams = transaction?.authenticationRequestParameters
  • initiate the authentication on GP Ecom side using the netceteraParams created at the previous step
val threeDSecure = Secure3dService
    .initiateAuthentication(recurringPaymentMethod, secureEcom)
    .withAmount(BigDecimal())
    .withCurrency("Currency")
    .withAuthenticationSource(AuthenticationSource.MobileSDK)
    .withOrderCreateDate(DateTime.now())
    .withOrderId(secureEcom.orderId)
    .withAddress(billingAddress, AddressType.Billing)
    .withAddress(shippingAddress, AddressType.Shipping)
    .withAddressMatchIndicator(false)
    .withMethodUrlCompletion(MethodUrlCompletion.No)
    .withMessageCategory(MessageCategory.PaymentAuthentication)
    .withCustomerEmail(customerEmail)
    .withApplicationId(netceteraParams.sdkAppID)
    .withSdkInterface(SdkInterface.Both)
    .withSdkUiTypes(*SdkUiType.entries.toTypedArray())
    .withReferenceNumber(netceteraParams.sdkReferenceNumber)
    .withSdkTransactionId(netceteraParams.sdkTransactionID)
    .withEncodedData(netceteraParams.deviceData)
    .withMaximumTimeout(5)
    .withEphemeralPublicKey(netceteraParams.sdkEphemeralPublicKey)
    .withChallengeRequestIndicator(ChallengeRequestIndicator.NoPreference)
    .execute()
  • check if the challenge is required from the previous call
threeDSecure.status == "CHALLENGE_REQUIRED"
  • create Netcetera challenge parameters using the response from the previous call
 val challengeParams = ChallengeParameters().apply {
    acsRefNumber = threeDSecure.acsReferenceNumber
    acsSignedContent = threeDSecure.payerAuthenticationRequest
    acsTransactionID = threeDSecure.acsTransactionId
    set3DSServerTransactionID(threeDSecure.serverTransactionId)
}
  • start the challenge using the netceteraTransaction and the challengeParams created at the previous steps
    You will receive the challenge result on the callback you pass in the doChallenge method
 netceteraTransaction.doChallenge(
    requireActivity(),
    challengeParams,
    object : ChallengeStatusReceiver {
        override fun completed(completionEvent: CompletionEvent?) {
        }

        override fun cancelled() {
        }

        override fun timedout() {
        }

        override fun protocolError(p0: ProtocolErrorEvent?) {
        }

        override fun runtimeError(p0: RuntimeErrorEvent?) {
        }
    }
)
  • check if the challenge was successful
completionEvent?.transactionStatus != "Y" //the challenge was completed successfully
  • charge the card with the amount authorized
val transaction = recurringPaymentMethod
    .charge(BigDecimal(Amount))
    .withCurrency(Currency)
    .execute()