Plans are not created on Stripe integration

If you’re looking for some help, it’s important to provide as much context as possible so that people are able to assist you. Try to always mention:

  • What’s your URL? the URL is https://apparent.today
  • What version of Ghost are you using? 4.5.0
  • What configuration? Self-hosted
  • What browser? Chrome, Brave
  • What errors or information do you see in the console?
    When logged out and trying to create a paid subscriber:
portal.min.js:3 GET https://apparent.today/members/api/member/ 401
GET https://apparent.today/members/api/session/ 400
POST https://apparent.today/members/api/create-stripe-checkout-session/ (after 60 seconds, runs into NGINX timeout.)
  • What steps could someone else take to reproduce the issue you’re having?
    • go to the webpage
    • open up the portal with the button “start listening for free”
    • try to create a user with paid subscription. (you won’t have to pay us to reproduce :slight_smile: )

Logs from Stripe end:

{
  "payment_method_types": {
    "0": "card"
  },
  "success_url": "https://apparent.today/?stripe=success",
  "cancel_url": "https://apparent.today/blog/?stripe=cancel",
  "customer_email": "redacted@redacted",
  "allow_promotion_codes": "false",
  "metadata": {
    "name": "MA",
    "requestSrc": "portal"
  },
  "subscription_data": {
    "trial_from_plan": "true",
    "items": {
      "0": {
        "plan": "price_1Ipy0AIDXc8PZpM0h2vaxuCK"   OFFENDING LINE
      }
    }
  }
}

Response body from Stripe

{
  "error": {
    "code": "resource_missing",
    "doc_url": "https://stripe.com/docs/error-codes/resource-missing",
    "message": "No such plan: 'price_1Ipy0AIDXc8PZpM0h2vaxuCK'",
    "param": "subscription_data[items][0][plan]",
    "type": "invalid_request_error"
  }
}

When I call the list of plans from the Stripe API manually, I get an empty list back.

Therefore I presume that when the integration took place, the plans are not created on the Stripe end. This is what happened in a long timeframe:

  • The website was created with 3.x
  • It was upgraded to 4.x
  • There might be TEST Stripe integration here, not sure.
  • A successful migration took place from another Ghost instance of same version
  • There might be TEST Stripe integration here, not sure.
  • The TEST integration was removed, and normal integration was done through an existing Stripe user, but a new account. All data required is entered to Stripe.
  • The mentioned steps are taken, and signup was not successful for subscribers.
  • Removed the integration
  • Re initialized the integration, now with the account present.
  • Signup still not successful for subscribers.

What do you recommend me to do? Any more information that I can give?

Update: Ghost DB has the prices under

 select * from stripe_prices;
+--------------------------+------------------------------------------------------------------+------------------------------------------------------------------+--------+---------------+----------+--------+-----------+----------+---------------------+---------------------+-------------+
| id                       | stripe_price_id                                                  | stripe_product_id | active | nickname      | currency | amount | type      | interval | created_at          | updated_at          | description |
+--------------------------+------------------------------------------------------------------+------------------------------------------------------------------+--------+---------------+----------+--------+-----------+----------+---------------------+---------------------+-------------+
| 609aaa0571a83f5183e10e5c | d46f4d6de40f9bb47c86b8c9abb8285182f0b10f3ac05b5ba8633417ecac2746 | REDACTED          |      1 | Complimentary | usd      |      0 | recurring | year     | 2021-05-11 16:00:05 | 2021-05-12 17:36:38 | NULL        |
| 609aaa0671a83f5183e10e5d | price_1Ipy0AIDXc8PZpM0h2vaxuCK                                   | REDACTED          |      1 | Monthly       | usd      |    500 | recurring | month    | 2021-05-11 16:00:06 | 2021-05-11 16:00:06 | NULL        |
| 609aaa0771a83f5183e10e5e | price_1Ipy0AIDXc8PZpM0fwEuJO7c                                   | REDACTED          |      1 | Yearly        | usd      |   5000 | recurring | year     | 2021-05-11 16:00:07 | 2021-05-11 16:00:07 | NULL        |
+--------------------------+------------------------------------------------------------------+------------------------------------------------------------------+--------+---------------+----------+--------+-----------+----------+---------------------+---------------------+-------------+

Stripe products:

 select * from stripe_products;
+--------------------------+--------------------------+------------------------------------------------------------------+---------------------+---------------------+
| id                       | product_id               | stripe_product_id                | created_at          | updated_at          |
+--------------------------+--------------------------+------------------------------------------------------------------+---------------------+---------------------+
| 609aaa0471a83f5183e10e5b | 609aa9c79f2890476eea551f | REDACTED                         | 2021-05-11 16:00:04 | 2021-05-11 16:00:04 |
+--------------------------+--------------------------+------------------------------------------------------------------+---------------------+---------------------+
1 row in set (0.00 sec)
MariaDB [apparent_content_prod]> select * from members_stripe_customers_subscriptions;
Empty set (0.00 sec)

But Stripe doesn’t have them:

{
  "object": "list",
  "data": [

  ],
  "has_more": false,
  "url": "/v1/plans"
}

Another update, I removed the account and created an account on Stripe from scratch. This did not resolve the issue, the plans are not created on the Stripe’s side.

The initial configuration that Ghost makes makes some API calls, I realized this, though I don’t think it is the issue, as Stripe is all green on its documentation page:

{
  "object": {
    "id": "transfers",
    "object": "capability",
    "account": "REDACTED",
    "requested": true,
    "requested_at": 1620912256,
    "requirements": {
      "current_deadline": null,
      "currently_due": [
      ],
      "disabled_reason": null,
      "errors": [
      ],
      "eventually_due": [
      ],
      "past_due": [
      ],
      "pending_verification": [
      ]
    },
    "status": "active"
  },
  "previous_attributes": {
    "requirements": {
      "disabled_reason": "requirements.fields_needed",
      "pending_verification": [
        "individual.verification.additional_document"     <----------
      ]
    },
    "status": "pending"
  }
}

I am sorry to update this often but I feel I am inching closer:

May 13 15:27:07 node[51806]: [2021-05-13 13:27:07] INFO "PUT /ghost/api/canary/admin/settings/" 200 711ms
May 13 15:27:07 node[51806]: [2021-05-13 13:27:07] INFO Migrating portal_plans setting from names to ids
May 13 15:27:07 node[51806]: [2021-05-13 13:27:07] INFO Could not find names in portal_plans setting, skipping migration

The database shows:

select id, `key`, value from settings where `key`='portal_plans';
+--------------------------+--------------+----------------------------------------------------------------+
| id                       | key          | value                                                          |
+--------------------------+--------------+----------------------------------------------------------------+
| 5fc4d87dd04616ed6ea42c95 | portal_plans | ["free","609aaa0771a83f5183e10e5e","609aaa0671a83f5183e10e5d"] |
+--------------------------+--------------+----------------------------------------------------------------+

This means that the migration was unnecessary, since plans are now stored relationally through id?

All right, realized that there is a new page for multiple products and prices for those products.
But when I try to save the product, I fail with 404. Ghost logs:

INFO "PUT /ghost/api/canary/admin/products/609aa9c79f2890476eea551f/" 404 344ms

Response to client:

{"errors":[{"message":"Resource not found error, cannot edit product.","context":"Resource could not be found.","type":"NotFoundError","details":null,"property":null,"help":null,"code":"resource_missing","id":"f8022f90-b3fe-11eb-b6e5-016213cc3d9d"}]}

Hi there, can anyone point me where the prices of products are in the database?

Hi @mehmetalianil - Is it possible that the price with id of price_1Ipy0AIDXc8PZpM0h2vaxuCK was in a different Stripe account to the one you have connected to Ghost?

can anyone point me where the prices of products are in the database?

Prices are stored in the stripe_prices table

Hi Fabien, that is perfect insight. I checked all our emails and actually found another stripe account, with a product with prices (actually 6 of them, one of the price_1Ipy0AIDXc8PZpM0h2vaxuCK, somehow we had integrated Stripe twice and created two sets of prices.) in the test mode of that account. I wasn’t able to remove the prices since they were associated to some dummy transactions, but I flushed all test data.

Somehow, that also did not resolve this issue. I ran the integration again, creating a new account. The situation persists, but I am confident that you are right. I think Stripe prices have UIDs that cannot be used, ever.

So, shall I manually alter the IDs of the prices from the DB?
Or is there a better way to do this? If I empty the table stripe_prices, would the prices be created on the go with new ids?

Does your site currently have active paying Members? I’m wondering what to best way to move forward is, if you do not have any active paying Members, it might be simplest to clean the DB of old data and to start fresh :thinking:

If I empty the table stripe_prices , would the prices be created on the go with new ids?

No, as of 4.5 Ghost no longer automatically creates prices in Stripe on boot. You would have to manually create them in the product settings.

1 Like

No active paying members, but there are members.
So by cleaning the old data from the DB, do you mean removing prices, or removing everyting?

But if I remove the prices, and get a product page without any prices listed in the admin panel of Ghost, and I add them manually, Ghost will create them on the fly through the Stripe API, right?

So before doing any of this I would suggest that you make backups!

I would suggest manually emptying the members_stripe_customers, members_stripe_customers_subscriptions, stripe_products and stripe_prices tables.

I would then disconnect Ghost from Stripe, and reconnect, making sure to connect to the correct Stripe Account

From here you should be able to manually add a Monthly and Yearly price in the Admin like you’ve described, and Ghost will create the Price and Product in Stripe

1 Like

Operation successful, did as you told me.
Thank you so much!

1 Like