checkout / checkout-sdk-net

Checkout SDK for Microsoft .NET
https://checkout.com
MIT License
21 stars 23 forks source link

PayPal via Payment Contexts documentation/SDK usage issue #365

Closed Antaris closed 8 months ago

Antaris commented 9 months ago

Environment

Description

PayPal via Payment Contexts - I might be misunderstanding something, but I think there are two areas the current SDK implementation of Payment Contexts is falling over:

1 - After creating a payment context, you should be able to fetch that context again after the customer has completed the PayPal flow, and capture the customer details:

{
  "payment_request": {
    "source": {
      "type": "paypal"
    },
    "amount": 2000,
    "currency": "USD",
    "payment_type": "Regular",
    "authorization_type": "Final",
    "capture": false,
    "customer": {
      "name": "John Smith",
      "email": "apm-payer@personal.example.com"
    },
    "shipping": {
      "first_name": "John Smith",
      "address": {
        "address_line1": "1 Main St",
        "city": "San Jose",
        "state": "CA",
        "zip": "95131",
        "country": "US"
      }
    },
    "items": [
      {
        "name": "laptop",
        "quantity": 1,
        "unit_price": 2000
      }
    ],
    "success_url": "http://www.example.com/success.html",
    "failure_url": "http://www.example.com/failure.html",
    "processing_channel_id": "pc_zmcw5ppbvr3ullkdlza6u4teoi"
  },
  "partner_metadata": {
    "customer_id": "WDB9U9PV7Y2KY",
    "order_id": "7YP86878G2990415D"
  }
}

Reference documentation section: https://www.checkout.com/docs/payments/add-payment-methods/paypal#Response_example_1

Note, the customer key in JSON. In the SDK API, the return type of the Customer property is object, which means we cannot determine the correct type, and the only recourse is to convert that node to JSON and back to a custom type that exposes the name and email subkeys?

using Checkout.Common;

namespace Checkout.Payments.Contexts
{
    public class PaymentContextDetailsResponse : HttpMetadata
    {
        public PaymentContextsResponse PaymentRequest { get; set; }

        public PaymentContextsPartnerMetadata PartnerMetadata { get; set; }

        public object Customer { get; set; } // <!-- What is the correct type here?
    }
}

2 - The reference documentation suggests that I can create a payment from a payment context ID:

{
  "payment_context_id":"pct_ckjrpk7vux4ejhghe6ssgkoy2y",
  "processing_channel_id": "{{NAS-processingChannel-personal}}"
}

Reference documentation section: https://www.checkout.com/docs/payments/add-payment-methods/paypal#Step_4:_Request_a_payment

But the PaymentsRequest class does not provide the facility to create a payment using a payment context ID.

Can you let me know if I have missed something obvious?

armando-rodriguez-cko commented 9 months ago

Thank you @Antaris! We will review it and give you a response.

armando-rodriguez-cko commented 9 months ago

Hello @Antaris, in the first and the second you are right, we will update it asap, thank you.

Antaris commented 9 months ago

Hi @armando-rodriguez-cko

I'm a little bit confused with the latest set of releases.

In 176f23ece5b529a7ba724f23c28a488b654a33d3 you've actually removed the Customer property from PaymentContextDetailsResponse, it was previous untyped as object, but I need this property to grab the PayPal customer's name and email address?

I've also noticed that when requesting a payment context, there is no field in the request object that represents user_action where I can specify that I want the user to 'Pay now' vs review their order.

This is covered in this part of your documentation: https://www.checkout.com/docs/payments/add-payment-methods/paypal#Step_1:_Request_a_Checkout.com_payment_context

I hate to put undue pressure on you, but Checkout.com have given us until 31st March to switch over to the V3 platform, and this is the only supported method for implementing PayPal through the API. Currently the SDK does not support the same operations, which is a blocker.

armando-rodriguez-cko commented 8 months ago

Hi @Antaris, I am sorry for the confusion, I understand you, when I implemented payment context I added customer by error because I followed a wrong documentation in that moment, we must follow the API reference: https://api-reference.checkout.com/#operation/requestAPaymentContext https://www.checkout.com/docs/payments/add-payment-methods/paypal

To get customer information you must use this endpoint: https://api-reference.checkout.com/#operation/getCustomerDetails I think, because payment context response has the customer id.

user_action can be implemented when you make a payment request in https://api-reference.checkout.com/#operation/requestAPaymentContext!path=processing/user_action&t=request

Please check this documentation if something is wrong I will help you, we love give support and help with everything.

Antaris commented 8 months ago

Hi @armando-rodriguez-cko

I think I understand how - I think there is some confusion between the published documentation for PayPal and the API reference.

Here is the documentation:

{
  "payment_request": {
    "source": {
      "type": "paypal"
    },
    "amount": 2000,
    "currency": "USD",
    "payment_type": "Regular",
    "authorization_type": "Final",
    "capture": false,
    "customer": {
      "name": "John Smith",
      "email": "apm-payer@personal.example.com"
    },
    "shipping": {
      "first_name": "John Smith",
      "address": {
        "address_line1": "1 Main St",
        "city": "San Jose",
        "state": "CA",
        "zip": "95131",
        "country": "US"
      }
    },
    "items": [
      {
        "name": "laptop",
        "quantity": 1,
        "unit_price": 2000
      }
    ],
    "success_url": "http://www.example.com/success.html",
    "failure_url": "http://www.example.com/failure.html",
    "processing_channel_id": "pc_zmcw5ppbvr3ullkdlza6u4teoi"
  },
  "partner_metadata": {
    "customer_id": "WDB9U9PV7Y2KY",
    "order_id": "7YP86878G2990415D"
  }
}

It suggests there is a key at payment_request.customer which contains this information, however this is not actually the case, and I can see now that the customer details are actually on the payment_request.shipping object (first_name, last_name, email), which means your code change is entirely correct. I can use this to complete this integration now I know this.

Additionally, in regards to user_action, the documentation doesn't actually mention this is a subkey of the processing node of the request. Now I know where to look I can see these properties in the .NET API.

Thanks for clearing this up. Can you raise an issue internally for the documentation, as it doesn't currently align with the API reference you refer to.

Thanks so much for your help!

armando-rodriguez-cko commented 8 months ago

I am glad to know. Thank you for your comments and I will tell documentation team to improve it.

Antaris commented 8 months ago

@armando-rodriguez-cko Apologies for reopening, I still encountering an issue. Here is an actual response from fetching the payment context:

{
  "status": "Created",
  "payment_request": {
    "source": {
      "type": "paypal"
    },
    "amount": 15000,
    "currency": "GBP",
    "payment_type": "Regular",
    "authorization_type": "Final",
    "reference": "<REDACTED>",
    "capture": true,
    "customer": {
      "name": "John Doe",
      "email": "sb-z5klz21518170@personal.example.com"
    },
    "shipping": {
      "first_name": "John Doe",
      "address": {
        "address_line1": "<REDACTED>",
        "city": "<REDACTED>",
        "state": "<REDACTED>",
        "zip": "<REDACTED>",
        "country": "GB"
      }
    },
    "processing": {
      "shipping_amount": 0,
      "user_action": "PAY_NOW"
    },
    "items": [
      {
        "name": "£150.00 Voucher",
        "quantity": 1,
        "unit_price": 15000,
        "total_amount": 0,
        "tax_amount": 0,
        "discount_amount": 0
      }
    ],
    "processing_channel_id": "<REDACTED>"
  },
  "partner_metadata": {
    "customer_id": "<REDACTED>",
    "order_id": "<REDACTED>"
  }
}

Notice the email address is not populated for the shipping element, but there is actually a customer node to the payment_request object, with a populated email address. The shipping object only contains the name in the first_name field, and because customer is not mapped on the .NET response object I can't get to it.

Unfortunately I am blocked again :-(

armando-rodriguez-cko commented 8 months ago

No problem @Antaris, please can you explain more the issue or paste your json or object request.

Do you set the email in shipping object and in the response is empty? Is this the issue? Anyway, your response json doesn't match with https://api-reference.checkout.com/#operation/getPaymentContext!c=200&path=payment_request&t=response

I gonna to ask now.

Antaris commented 8 months ago

@armando-rodriguez-cko This is the response from call to fetch a payment context, so yes the response doesn't align with the API reference, I'm not sure there is anything I can do to make it respond the way it should. It feels like there is a disconnect between your API reference, the actual data that comes out, and the requirements for integrating PayPal on the V3 APi via this SDK?

armando-rodriguez-cko commented 8 months ago

Hi @Antaris! Documentation will be updated next week. Thank you.

Antaris commented 8 months ago

Hi @Antaris! Documentation will be updated next week. Thank you.

Hi @armando-rodriguez-cko what's the outcome though, is the docs wrong, or the API ref, as the system gives the data I need, but the SDK doesn't?

armando-rodriguez-cko commented 8 months ago

At the moment I don't know. As soon as I have more information I will share it with you. If you'd like and want to propose changes in the code, I'd be happy to review them. Do you need only customer object and status in the get response, here: https://api-reference.checkout.com/#operation/getPaymentContext!c=200&path=payment_request&t=response?

Antaris commented 8 months ago

Hi @armando-rodriguez-cko

Yeah, what I need is the customer JSON node to be mapped to something by the SDK? I'm quite concerned about the cut-off of March 31st for the platform migration though

armando-rodriguez-cko commented 8 months ago

Hi @Antaris, I am checking the new properties to add it to the SDK.