B4J Question Cybersource

aaronk

Well-Known Member
Licensed User
Longtime User
Hi,

Just wondering if anyone has used cybersource with B4X before ?

I am trying to use it with my B4J app. My bank has provided me a sandbox account for testing, but trying to work out how to interface the API with my B4J app.

For testing I have used ChatGPT to help me write the following, but not sure if it's correct etc.

I am waiting for confirmation from my bank for the Merchant ID, but thought I would reach out to see if anyone has used Cybersource before ?


B4X:
Sub Class_Globals
    Private merchantId As String
    Private apiKeyId As String
    Private secretKey As String
    Private baseUrl As String = "https://apitest.cybersource.com"
End Sub

Public Sub Initialize(mId As String, keyId As String, secKey As String)
    merchantId = mId
    apiKeyId = keyId
    secretKey = secKey
End Sub

' =========================================================
' 👤 CREATE CUSTOMER (TMS)
' =========================================================
Public Sub CreateCustomer(customerId As String, email As String) As ResumableSub

    Dim endpoint As String = "/tms/v2/customers"

    Dim payload As Map = CreateMap( _
        "buyerInformation": CreateMap( _
            "merchantCustomerID": customerId, _
            "email": email _
        ) _
    )

    Dim gen As JSONGenerator
    gen.Initialize(payload)
    Dim body As String = gen.ToString

    Dim job As HttpJob
    job.Initialize("", Me)

    Dim url As String = baseUrl & endpoint
    job.GetRequest.SetContentType("application/json")
    job.PostString(url, body)
    

    Dim headers As Map = CreateSignature("POST", endpoint, body)

    For Each k As String In headers.Keys
        job.GetRequest.SetHeader(k, headers.Get(k))
    Next

    Wait For (job) JobDone(job As HttpJob)

    If job.Success Then
        Dim parser As JSONParser
        parser.Initialize(job.GetString)
        Dim res As Map = parser.NextObject
        job.Release
        Return res
    Else
        Log("❌ Cybersource Error: " & job.ErrorMessage)
        Log(job.GetString)
        job.Release
        Return Null
    End If

End Sub

' =========================================================
' 🔐 CREATE SIGNATURE (HTTP SIGNATURE)
' =========================================================
Private Sub CreateSignature(method As String, resource As String, body As String) As Map

    Dim headers As Map
    headers.Initialize

    Dim date As String = GetGMTDate

    Dim digest As String = ""
    If body <> "" Then
        digest = "SHA-256=" & B64Encode(SHA256(body))
    End If

    Dim signatureString As String = _
        "host: apitest.cybersource.com" & CRLF & _
        "date: " & date & CRLF

    If body <> "" Then signatureString = signatureString & "digest: " & digest & CRLF

    signatureString = signatureString & _
        "(request-target): " & method.ToLowerCase & " " & resource & CRLF & _
        "v-c-merchant-id: " & merchantId

    Dim sig() As Byte = HmacSHA256(secretKey, signatureString)
    Dim signature As String = B64Encode(sig)

    Dim authHeader As String = _
        $"keyid="${apiKeyId}", algorithm="HmacSHA256", headers="host date digest (request-target) v-c-merchant-id", signature="${signature}""$

    headers.Put("Host", "apitest.cybersource.com")
    headers.Put("Date", date)
    headers.Put("v-c-merchant-id", merchantId)
    headers.Put("Signature", authHeader)

    If digest <> "" Then headers.Put("Digest", digest)

    Return headers

End Sub

' =========================================================
' 🔐 HMAC SHA256 (CORRECT B4J VERSION)
' =========================================================
Private Sub HmacSHA256(key As String, data As String) As Byte()

    Dim macJO As JavaObject
    macJO.InitializeStatic("javax.crypto.Mac")

    Dim mac As JavaObject = macJO.RunMethod("getInstance", Array("HmacSHA256"))

    Dim keySpec As JavaObject
    keySpec.InitializeNewInstance("javax.crypto.spec.SecretKeySpec", _
        Array(key.GetBytes("UTF8"), "HmacSHA256"))

    mac.RunMethod("init", Array(keySpec))

    Return mac.RunMethod("doFinal", Array(data.GetBytes("UTF8")))

End Sub

' =========================================================
' 🔐 SHA256 DIGEST
' =========================================================
Private Sub SHA256(text As String) As Byte()

    Dim jo As JavaObject
    jo.InitializeStatic("java.security.MessageDigest")

    Dim md As JavaObject = jo.RunMethod("getInstance", Array("SHA-256"))
    Return md.RunMethod("digest", Array(text.GetBytes("UTF8")))

End Sub

' =========================================================
' 🔐 BASE64 ENCODING (JAVA STANDARD)
' =========================================================
Private Sub B64Encode(b() As Byte) As String

    Dim jo As JavaObject
    jo.InitializeStatic("java.util.Base64")

    Dim encoder As JavaObject = jo.RunMethodJO("getEncoder", Null)
    Return encoder.RunMethod("encodeToString", Array(b))

End Sub

' =========================================================
' 📅 GMT DATE (CYBERSOURCE SAFE FORMAT)
' =========================================================
Private Sub GetGMTDate As String

    Dim jo As JavaObject
    jo.InitializeStatic("java.time.ZonedDateTime")

    Dim zdt As JavaObject = jo.RunMethod("now", Null)

    Dim fmt As JavaObject
    fmt.InitializeStatic("java.time.format.DateTimeFormatter")

    Dim localeJO As JavaObject
    localeJO.InitializeStatic("java.util.Locale")

    Dim usLocale As JavaObject = localeJO.GetField("US")

    Dim formatter As JavaObject = fmt.RunMethod("ofPattern", _
        Array("EEE, dd MMM yyyy HH:mm:ss 'GMT'", usLocale))

    Return zdt.RunMethod("format", Array(formatter))

End Sub
 
Top