0

I'm currently working on interactions from SFDC to Worldline APIs and I have an issue with the authentication to their API. I have followed what they wrote here and the generated authorization header format is identical to what gets generated in the public Postman Worldline collection, but I get the 403 status code, and in Postman it works fine.

My static method gets called inside an

My Apex code looks like this:

public with sharing class GenerateWorldlineAuthorization {
    //GET Http Callout for Worldline Authorization
    public static String getWorldlineAPIAuthorization() {
        Http httpCall = new Http();
        HttpRequest httpRequest = new HttpRequest();
        String apiKey = 'ABCDEFGH11112233FGTY';
        String apiSecret = 'ADFGC56DSFSDAD89PLI/GHTERRERADSADAD4554GHFFD==';
        String pspId = 'userpspId';
        String stringToHash;
        String requestMethod = 'GET';
        String contentType = '';
        String hostname = 'payment.preprod.direct.worldline-solutions.com';
        String uriResource = '/services/testconnection';
        String endpointURL = '/v2/' + pspId + uriResource;
        String currentTime = '';
        String encodedSignature = '';
        String authorizationValue = '';
        String responseString = '';
        Datetime currentDateTime = Datetime.now();

        currentTime = currentDateTime.format('EEE, dd MMM yyyy HH:mm:ss') + ' GMT';

        if (requestMethod != 'GET') {
            contentType = 'application/json';
        }

        stringToHash = requestMethod + '\n' + contentType + '\n' + currentTime + '\n' + endpointURL + '\n';

        System.debug(stringToHash);

        Blob stringToHashBlob = Blob.valueOf(stringToHash);
        String encodedHash = EncodingUtil.base64Encode(stringToHashBlob);
        Blob encodeHashBlob = EncodingUtil.base64Decode(encodedHash);
        Blob apiSecretBlob = EncodingUtil.base64Decode(apiSecret);
        Blob hmacSHA256blob = Crypto.generateMac('HmacSHA256',encodeHashBlob,apiSecretBlob);
        Blob signature = Crypto.generateDigest('SHA256', hmacSHA256blob);

        encodedSignature = EncodingUtil.base64Encode(signature);
        authorizationValue = 'GCS v1HMAC:' + apiKey + ':' + encodedSignature;

        httpRequest.setEndpoint('https://' + hostname + endpointURL);
        httpRequest.setMethod('GET');
        httpRequest.setHeader('Date', currentTime);
        httpRequest.setHeader('Authorization', authorizationValue);
        httpRequest.setHeader('Host', hostname);
        httpRequest.setHeader('Accept-Encoding', 'gzip, deflate, br');
        httpRequest.setHeader('Connection', 'keep-alive');

        HttpResponse httpResponse = httpCall.send(httpRequest);

        System.debug('Authorization:' + httpRequest.getHeader('Authorization'));
        System.debug('Date:' + httpRequest.getHeader('Date'));
        System.debug('Host:' + httpRequest.getHeader('Host'));

        System.debug('https://' + hostname + endpointURL);
        System.debug('Response: ' + httpResponse.getBody());

        responseString = 'Response code: '+ String.valueOf(httpResponse.getStatusCode()) + '. Response Status: ' + httpResponse.getStatus();

        return responseString;
    }
}
public with sharing class CreateWorldlinePayment {
    //Method that calls the authorization fpr the Worldline APIs
    @Future(Callout=true)
    public static void getPaymentGatewayAuthorization() {
         String paymentAuthorizationResponse = GenerateWorldlineAuthorization.getWorldlineAPIAuthorization();

        System.debug(paymentAuthorizationResponse);
    }
}
trigger CardPaymentTrigger on Asset (after update) {
    if (Trigger.isUpdate) {
        if (Trigger.isAfter) {
            for (Asset asset : Trigger.new) {
                CreateWorldlinePayment.getPaymentGatewayAuthorization();
            }
        }
    }
}
2
  • 2
    Please remove the apikey and secret code from the Question.
    – Saroj Bera
    Commented Jan 23, 2023 at 12:33
  • 3
    @SarojBera, those are dummy values. I wouldn't put the real ones in a public place. Commented Jan 23, 2023 at 14:43

1 Answer 1

0

I fixed the issue, it seems I was doing to much. So, instead of writing

 Blob stringToHashBlob = Blob.valueOf(stringToHash);
    String encodedHash = EncodingUtil.base64Encode(stringToHashBlob);
    Blob encodeHashBlob = EncodingUtil.base64Decode(encodedHash);
    Blob apiSecretBlob = EncodingUtil.base64Decode(apiSecret);
    Blob hmacSHA256blob = Crypto.generateMac('HmacSHA256',encodeHashBlob,apiSecretBlob);
    Blob signature = Crypto.generateDigest('SHA256', hmacSHA256blob);

, all I needed to write was

Blob hmacSHA256blob = Crypto.generateMac('HmacSHA256',Blob.valueOf(stringToHash),Blob.valueOf(apiSecret));
encodedSignature = EncodingUtil.base64Encode(hmacSHA256blob);

and it worked.

Hope this helps anybody who faces similarr problems in the future.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .