Robert Green MBA
Robert Green MBA

Reputation: 1866

Google Pay Integration Issue with Authorize.net – Invalid Ownership Error

I'm trying to integrate Google Pay with Authorize.net, but I'm encountering an error that suggests my account setup might be incorrect. Specifically, I see an "invalid ownership" error when attempting a transaction.

Error Code 153 
There was an error processing the payment data. Invalid ownership..

What I’ve Done So Far:

  1. Followed the Authorize.net Google Pay setup guide.
  2. Ensured my Authorize.net account is on a supported processor.
  3. Generated my Authorize.net API Login ID and Transaction Key.
  4. Enabled the service in the Authorize.net Merchant Interface.
  5. Confirmed my app meets Google Pay Developer Requirements.
  6. Issue: I think I didn’t generate my Google Pay Public Key properly.
    • Under the "Requirements for Google Pay with Authorize.net" section, it states: "You must generate a Google Pay public key."
    • In the "Enabling Google Pay in the Merchant Interface" section, Step 5 says to enter a KeySet ID from Google, which I don’t think I have.

Questions:

  1. How do I correctly generate the Google Pay Public Key and KeySet ID for Authorize.net?
  2. In Google Pay & Wallet Console, what exact steps should I follow to get the KeySet ID?
  3. Could the "invalid ownership" error be related to not having the correct public key set up?

Screenshots:

I've attached relevant screenshots of my setup to show where I'm stuck.

Any help would be greatly appreciated! enter image description here enter image description here


Update 01/29/2025 -- Added code -- full end-to-end steps

Primary Issue

Tech Stack: Ionic 6 / Angular 16 / Capacitor / C# .NET API

Google Pay Library: @ionic-enterprise/google-pay": "^2.2.2

When I make my request to Google Pay to authorize a transaction, I send to google (after initializing the payment instance) this GooglePayTransactionInfo object.

const googlePayTransactionInfo: GooglePayTransactionInfo = {
  countryCode: 'US',
  currencyCode: 'USD',
  totalPrice: amount.toString(),
  totalPriceStatus: 'FINAL',
};

The user clicks the “Pay with Google Pay” button. Our mobile app calls on GooglePay.makePaymentRequest({..}) via this makePaymentRequest off our Component GooglePayService.

const response = await this.googlePayService.makePaymentRequest(googlePayTransactionInfo);

The response from this request from Google Pay contains the Token that we need to use in the Authorize.NET C# SDK to process the Google Payment as shown in the sample implementation code.

The response we get back looks like this:

enter image description here

... and a few more details about the tokenizationData

After we get this response, we convert the token paymentMethodData.tokenizationData.token to its base-64 representation

obj.Token = window.btoa(response.paymentMethodData.tokenizationData.token);

Next, we, as per the Authorize.NET C# SDK example, call our API which uses the Authorize.NET C# SDK as follows: (notice we set the opaqueDataType.dataValue equal to the above encrypted token ...window.btoa(..) )

[HttpPost("api/payment/a/b")]
[ProducesResponseType(200)]
public async Task<ActionResult> ProcessGooglePayPaymentIntentAsync(GooglePayIntentDto googlePayIntentDto)
{
    try
    {
        var environment = Configuration["Environment"];
        var apiLoginId = Configuration["ApiLoginId"];
        var transactionKey = Configuration["TransactionKey"];

        environment.ValidateArgNotNull(nameof(environment));
        apiLoginId.ValidateArgNotNull(nameof(apiLoginId));
        transactionKey.ValidateArgNotNull(nameof(transactionKey));

        if (googlePayIntentDto.Token == null)
        {
            throw new System.Exception("Token is null.");
        }

        // Set up API credentials
        ApiOperationBase<ANetApiRequest, ANetApiResponse>.RunEnvironment = environment == "Production" ? AuthorizeNet.Environment.PRODUCTION : AuthorizeNet.Environment.SANDBOX; 

        ApiOperationBase<ANetApiRequest, ANetApiResponse>.MerchantAuthentication = new merchantAuthenticationType()
        {
            name = apiLoginId, // API Login ID
            ItemElementName = ItemChoiceType.transactionKey,
            Item = transactionKey // Transaction Key
        };

        var decimalAmount = decimal.Parse(googlePayIntentDto.AmountAsString);

        var opaqueData = new opaqueDataType()
        {
            dataDescriptor = "COMMON.GOOGLE.INAPP.PAYMENT",
            dataValue = googlePayIntentDto.Token,
        };

        var paymentType = new paymentType()
        {
            Item = opaqueData
        };

        var lineItems = new lineItemType[]
        {
            new lineItemType()
            {
                itemId = "1",
                name = "My Sample Product",
                description =”My sample product description”,
                quantity = 1,
                unitPrice = decimalAmount
            }
        };

        var tax = new extendedAmountType()
        {
            amount = 0,
            name = "Zero Tax",
            description = "Zero Tax"
        };

        var userFields = new userField[]
        {
            new userField()
            {
                name = "UserId",
                value = Constants.UserId.ToString()
            }
        };

        var transactionRequest = new transactionRequestType()
        {
            transactionType = transactionTypeEnum.authCaptureTransaction.ToString(),
            amount = decimalAmount,
            payment = paymentType,
            lineItems = lineItems,
            tax = tax,
            userFields = userFields
        };

        var request = new createTransactionRequest { transactionRequest = transactionRequest };

        var controller = new createTransactionController(request);
        controller.Execute();

        var response = controller.GetApiResponse();
        var transactionResult = "";

And everything seems to work properly, but the response that we get via

var response = controller.GetApiResponse();

is the following:

enter image description here

Upvotes: -1

Views: 135

Answers (0)

Related Questions