Home > Enterprise >  Receiving unknown response body
Receiving unknown response body

Time:10-27

I am implementing the Authorize.net credit card API. The API always gives me a 200 response code regardless if the transaction is successful or it is declined. But it gives the one response body for successful transaction and a different one for declined transaction.

type AuthorizeApprovedResponse struct {
    TransactionResponse struct {
        ResponseCode   string `json:"responseCode"`
        AuthCode       string `json:"authCode"`
        AvsResultCode  string `json:"avsResultCode"`
        CvvResultCode  string `json:"cvvResultCode"`
        CavvResultCode string `json:"cavvResultCode"`
        TransID        string `json:"transId"`
        RefTransID     string `json:"refTransID"`
        TransHash      string `json:"transHash"`
        TestRequest    string `json:"testRequest"`
        AccountNumber  string `json:"accountNumber"`
        AccountType    string `json:"accountType"`
        Messages       []struct {
            Code        string `json:"code"`
            Description string `json:"description"`
        } `json:"messages"`
        UserFields []struct {
            Name  string `json:"name"`
            Value string `json:"value"`
        } `json:"userFields"`
        TransHashSha2                          string `json:"transHashSha2"`
        SupplementalDataQualificationIndicator int    `json:"SupplementalDataQualificationIndicator"`
        NetworkTransID                         string `json:"networkTransId"`
    } `json:"transactionResponse"`
    RefID    string `json:"refId"`
    Messages struct {
        ResultCode string `json:"resultCode"`
        Message    []struct {
            Code string `json:"code"`
            Text string `json:"text"`
        } `json:"message"`
    } `json:"messages"`
}

type AuthorizeDeclinedResponse struct {
    TransactionResponse struct {
        ResponseCode   string `json:"responseCode"`
        AuthCode       string `json:"authCode"`
        AvsResultCode  string `json:"avsResultCode"`
        CvvResultCode  string `json:"cvvResultCode"`
        CavvResultCode string `json:"cavvResultCode"`
        TransID        string `json:"transId"`
        RefTransID     string `json:"refTransID"`
        TransHash      string `json:"transHash"`
        TestRequest    string `json:"testRequest"`
        AccountNumber  string `json:"accountNumber"`
        AccountType    string `json:"accountType"`
        Errors         []struct {
            ErrorCode string `json:"errorCode"`
            ErrorText string `json:"errorText"`
        } `json:"errors"`
        UserFields []struct {
            Name  string `json:"name"`
            Value string `json:"value"`
        } `json:"userFields"`
        TransHashSha2                          string `json:"transHashSha2"`
        SupplementalDataQualificationIndicator int    `json:"SupplementalDataQualificationIndicator"`
        NetworkTransID                         string `json:"networkTransId"`
    } `json:"transactionResponse"`
    RefID    string `json:"refId"`
    Messages struct {
        ResultCode string `json:"resultCode"`
        Message    []struct {
            Code string `json:"code"`
            Text string `json:"text"`
        } `json:"message"`
    } `json:"messages"`
}

Here is my problem, which struct to use. I was thinking of trying an interface{} and then try to cast it to a struct?

err := json.Unmarshal(b, &whichStructToUse)
    if err != nil {
        panic(err.Error())
    }

Any advice on how to Unmarshal the response when I don't know which struct to use?

CodePudding user response:

The API always gives me a 200 response code regardless if the transaction is successful or it is declined.

I feel your pain.

There's only one difference between the two responses, success has Messages and failure has Errors. Combine them.

type CommonResponse struct {
    TransactionResponse struct {
        ResponseCode   string `json:"responseCode"`
        AuthCode       string `json:"authCode"`
        AvsResultCode  string `json:"avsResultCode"`
        CvvResultCode  string `json:"cvvResultCode"`
        CavvResultCode string `json:"cavvResultCode"`
        TransID        string `json:"transId"`
        RefTransID     string `json:"refTransID"`
        TransHash      string `json:"transHash"`
        TestRequest    string `json:"testRequest"`
        AccountNumber  string `json:"accountNumber"`
        AccountType    string `json:"accountType"`
        Messages       []struct {
            Code        string `json:"code"`
            Description string `json:"description"`
        } `json:"messages"`
        Errors         []struct {
            ErrorCode string `json:"errorCode"`
            ErrorText string `json:"errorText"`
        } `json:"errors"`
        UserFields []struct {
            Name  string `json:"name"`
            Value string `json:"value"`
        } `json:"userFields"`
        TransHashSha2                          string `json:"transHashSha2"`
        SupplementalDataQualificationIndicator int    `json:"SupplementalDataQualificationIndicator"`
        NetworkTransID                         string `json:"networkTransId"`
    } `json:"transactionResponse"`
    RefID    string `json:"refId"`
    Messages struct {
        ResultCode string `json:"resultCode"`
        Message    []struct {
            Code string `json:"code"`
            Text string `json:"text"`
        } `json:"message"`
    } `json:"messages"`
}

Then use that to unmarshall and check for Errors.

    var response CommonResponse;
    json.Unmarshal([]byte(jsonString), &response)
    if len(response.Error) == 0 {
        fmt.Println("Success!")
    } else {
        fmt.Println("Error!")
    }

For the more general case, you can unmarshall to a map[string]interface{}.

var result map[string]interface{}
json.Unmarshal([]byte(jsonString), &result)

Demonstration.

  • Related