Shopify / shopify-api-ruby

ShopifyAPI is a lightweight gem for accessing the Shopify admin REST and GraphQL web services.
MIT License
1.06k stars 473 forks source link

Creates a recurring application charge fails in production #1341

Closed felixding closed 1 month ago

felixding commented 1 month ago

I'm trying to create a recurring application charge as follows:

recurring_application_charge = ShopifyAPI::RecurringApplicationCharge.new(session: Shop.first.shopify_session)
recurring_application_charge.name = "Super Duper Plan"
recurring_application_charge.price = 10.0
recurring_application_charge.return_url = "http://super-duper.shopifyapps.com/"
recurring_application_charge.save!

It works well in development with recurring_application_charge.test = true.

But it fails in production (after removing recurring_application_charge.test = true, of course).

The API returns {"error_reference":"If you report this error, please include this id: 60dcfc7c-08b1-433d-a16a-78d5f8827616-1727746893."}

The Shopify session is valid. I can get the product images using the same session:

Loading production environment (Rails 7.1.3.3)
irb(main):001> Shop.first.product_images
W, [2024-10-02T01:28:33.734932 #1]  WARN -- : Deprecated request to Shopify API at products.json, received reason: https://shopify.dev/api/admin-rest/latest/resources/product
=>
["https://cdn.shopify.com/s/files/1/0829/7712/8724/products/gift_card.png?v=1695028426",
 "https://cdn.shopify.com/s/files/1/0829/7712/8724/products/snowboard_wax.png?v=1695028430",
 ...]

But as mentioned above, this failed:

irb(main):002> recurring_application_charge = ShopifyAPI::RecurringApplicationCharge.new(session: Shop.first.shopify_session)
irb(main):003> recurring_application_charge.name = "Super Duper Plan"
irb(main):004> recurring_application_charge.price = 10.0
irb(main):005> recurring_application_charge.return_url = "http://super-duper.shopifyapps.com"
irb(main):006> recurring_application_charge.test = nil
irb(main):007> recurring_application_charge.save!
(irb):7:in `<main>': {"error_reference":"If you report this error, please include this id: c06a3502-358d-442e-8728-fb38f40ef254-1727832529."} (ShopifyAPI::Errors::HttpResponseError)

Why?

felixding commented 1 month ago

I've also tried to debug with CURL as per documentation. But the official sample code doesn't work. Probably because the API endpoint is behind Cloudflare which blocks CURL requests.

lizkenyon commented 1 month ago

Hi there!

This seem like it may have been an issue with the underlying API, that has now been resolved and not this library.

I was able to successfully create a recurring application charge with CURL.

Going to close this issue. Please re-open if you do believe there is a bug in this library.

felixding commented 1 month ago

Thanks for the update. I just tried once again using this gem and it didn't work. What do you mean that it has been resolved?

lizkenyon commented 1 month ago

If you are seeing the same errors with CURL or Postman, then I would expect the issue to be with the API directly and not with this library. Are you still seeing errors when you use CURL or Postman?

felixding commented 1 month ago

The CURL command from the documentation doesn't work:

curl  -d '{"recurring_application_charge":{"name":"Super Duper Plan","price":10.0,"return_url":"http://super-duper.shopifyapps.com","capped_amount":100,"terms":"$1 for 1000 emails"}}' \
-X POST "https://redacted.myshopify.com/admin/api/2024-07/recurring_application_charges.json" \
-H "X-Shopify-Access-Token: redacted" \
-H "Content-Type: application/json"

Yes. That's the full request and response. The API returns nothing.

I had to add -v to know what happened:

curl -v -d '{"recurring_application_charge":{"name":"Super Duper Plan","price":10.0,"return_url":"http://super-duper.shopifyapps.com","capped_amount":100,"terms":"$1 for 1000 emails"}}' \
-X POST "https://redacted.myshopify.com/admin/api/2024-07/recurring_application_charges.json" \
-H "X-Shopify-Access-Token: redacted" \
-H "Content-Type: application/json"

Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 23.227.38.74:443...
* Connected to redacted.myshopify.com (23.227.38.74) port 443
* ALPN: curl offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=myshopify.com
*  start date: Aug  9 15:23:07 2024 GMT
*  expire date: Nov  7 15:23:06 2024 GMT
*  subjectAltName: host "redacted.myshopify.com" matched cert's "*.myshopify.com"
*  issuer: C=US; O=Let's Encrypt; CN=E6
*  SSL certificate verify ok.
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://redacted.myshopify.com/admin/api/2024-07/recurring_application_charges.json
* [HTTP/2] [1] [:method: POST]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: redacted.myshopify.com]
* [HTTP/2] [1] [:path: /admin/api/2024-07/recurring_application_charges.json]
* [HTTP/2] [1] [user-agent: curl/8.4.0]
* [HTTP/2] [1] [accept: */*]
* [HTTP/2] [1] [x-shopify-access-token: redacted]
* [HTTP/2] [1] [content-type: application/json]
* [HTTP/2] [1] [content-length: 172]
> POST /admin/api/2024-07/recurring_application_charges.json HTTP/2
> Host: redacted.myshopify.com
> User-Agent: curl/8.4.0
> Accept: */*
> X-Shopify-Access-Token: redacted
> Content-Type: application/json
> Content-Length: 172
>
< HTTP/2 403
< date: Fri, 04 Oct 2024 04:33:47 GMT
< content-type: text/html
< x-sorting-hat-podid: 275
< x-sorting-hat-shopid: 82977128724
< vary: Accept-Encoding
< referrer-policy: origin-when-cross-origin
< x-frame-options: DENY
< x-shopid: 82977128724
< x-shardid: 275
< x-stats-userid:
< x-stats-apiclientid: 156691464193
< x-stats-apipermissionid: 754988548372
< x-shopify-api-version: 2024-07
< http_x_shopify_shop_api_call_limit: 1/40
< x-shopify-shop-api-call-limit: 1/40
< strict-transport-security: max-age=7889238
< x-request-id: 408e1aa2-fe05-4a9c-a9d5-8daa97e9de58-1728016426
< server-timing: processing;dur=60
< content-security-policy: default-src 'self' data: blob: 'unsafe-inline' 'unsafe-eval' https://* shopify-pos://*; block-all-mixed-content; child-src 'self' https://* shopify-pos://*; connect-src 'self' wss://* https://*; frame-ancestors 'none'; img-src 'self' data: blob: https:; script-src https://cdn.shopify.com https://cdn.shopifycdn.net https://checkout.shopifycs.com https://api.stripe.com https://mpsnare.iesnare.com https://appcenter.intuit.com https://www.paypal.com https://js.braintreegateway.com https://c.paypal.com https://maps.googleapis.com https://www.google-analytics.com https://v.shopify.com 'self' 'unsafe-inline' 'unsafe-eval'; upgrade-insecure-requests; report-uri /csp-report?source%5Baction%5D=create&source%5Bapp%5D=Shopify&source%5Bcontroller%5D=admin%2Frecurring_application_charges&source%5Bsection%5D=admin_api&source%5Buuid%5D=408e1aa2-fe05-4a9c-a9d5-8daa97e9de58-1728016426
< x-content-type-options: nosniff
< x-download-options: noopen
< x-permitted-cross-domain-policies: none
< x-xss-protection: 1; mode=block; report=/xss-report?source%5Baction%5D=create&source%5Bapp%5D=Shopify&source%5Bcontroller%5D=admin%2Frecurring_application_charges&source%5Bsection%5D=admin_api&source%5Buuid%5D=408e1aa2-fe05-4a9c-a9d5-8daa97e9de58-1728016426
< x-dc: gcp-us-central1,gcp-us-east1,gcp-us-east1
< alt-svc: h3=":443"; ma=86400
< cf-cache-status: DYNAMIC
< report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v4?s=fF9IAlhm4tKN81WKXEMCM7XyDEbSwpai0G%2B3UXLDjMaM3A3ANIwGITolrvOz9bINJNkeh2PnJ0NrT6rgDHGpvozkYHZP3D9UCIXTi2P2NycM1iziR6jEFwA%2FMWOOCZNC37jM5hk%3D"}],"group":"cf-nel","max_age":604800}
< nel: {"success_fraction":0.01,"report_to":"cf-nel","max_age":604800}
< server-timing: cfRequestDuration;dur=280.999899
< server: cloudflare
< cf-ray: 8cd274ab2981d55e-NRT
<
* Connection #0 to host redacted.myshopify.com left intact
*

Apparently the request was blocked by Cloudflare, as mentioned above.