worknenjoy / gitpay

Bounties for issues on demand. Be rewarded by learning, using Git workflow and continuous integration
http://gitpay.me
Other
181 stars 161 forks source link

Update issue imported from Gitpay after receive an invoice paid webhook #886

Closed alexanmtz closed 1 year ago

alexanmtz commented 2 years ago

When a webhook send to update payment or invoice, we should put into the Gitpay flow:

Webhook sent

{
  "object": {
    "id": ["in_test"]
    "object": "invoice",
    "amount_due": 6490,
    "charge": ["ch_test),
    "currency": "usd",
    "customer": ["cus_test),
    "default_payment_method": null,
    "default_source": null,
    "number": "USD-0016",
    "payment_intent": ["pi_test"]
    "period_end": 1636030341,
    "period_start": 1636030341,
    "status": "paid",
    "subscription": null,
    "total": 6490,
...
  }
}

Why

We sometimes do payments from external sources, mainly using Stripe invoices from clients We need to recognize this event to get the payment part of the test already charged for a task

Level

Medium

Current behavior

When a payment is done on Stripe, the task is not on Gitpay

Expected behavior

When I use the metatag on Stripe about order_id I should create an order on Gitpay

Useful links

How to reproduce the user scenario

What you will need to complete this issue

Stripe development keys

Tips

EDIT

To clarify this, we will consider the following situation

We create orders from this screen that it goes directly on Stripe and can be paid

Screenshot 2022-03-24 at 10 33 05

This invoice is created here: https://github.com/worknenjoy/gitpay/blob/42350a041d25fee37c6b7cec056f7db1d05b7744/frontend/src/components/task/assignment/AssignActions.js#L134

is an order of the type invoice-item

First of all, see the customer_id here: https://github.com/worknenjoy/gitpay/blob/42350a041d25fee37c6b7cec056f7db1d05b7744/frontend/src/components/task/assignment/AssignActions.js#L143

If I'm creating, the invoice will be created, with my customer_id on Stripe Now the first change we need to do:

Subtask 1) Change this screen to have an email field, if I wish to pass another other than mine, because we need to pass another customer other than the one is sending

We support clients paying directly by invoice and they don't need to have a Gitpay account

So we will pass the customer id and for and a user-id we have an issue

We have two options: 1) See the impact of this implementation, to create order without a user 2) Add to the user an activated flag and create new users with activated false and any other user true by default. This user will have a role of funding

Subtask 2) From the Customer id input by user, get the customer on Stripe and try to fill only with e-mail: https://github.com/worknenjoy/gitpay/blob/42350a041d25fee37c6b7cec056f7db1d05b7744/frontend/src/components/task/assignment/AssignActions.js#L138

When this invoice is created the next step is to receive the webhook above when is paid and update this order.

This order created should be list as payments done in the task page

_Subtask 3) Save meta attributes on the invoice-item order with the taskid to be retrieved later by the webhook

_Subtask 4) On the webhooks, you will receive the invoice paid webhook to change the status on Gitpay to paid https://github.com/worknenjoy/gitpay/blob/e64d13d2d17381a617a867268e1e7348b0dec101/modules/app/controllers/webhook.js

GitpayPop commented 2 years ago

Gitpay is an Open Source platform to reward contributors to get things done 💝

About Gitpay platform.

For portuguese, you can access the portuguese version

📋 Step by Step

If you are the task owner who created this issue

If you want to contribute and be rewarded

📋 Task status

Good to know

  1. If you are familiar with the terminal or would like to learn it, here is a great tutorial on how to send a pull request using the terminal.

  2. For a more compreenhensive guide to create the Pull Request properly, you can access: https://guides.github.com/activities/hello-world/

  3. You can edit files directly in your browser

🤔❓ Questions

Leave a comment below! This issue was a comment made by our GitpayBot Gitpay Bot.

alexanmtz commented 2 years ago

@VictorAlessander

Here is the right webhook received:

{
  "id": ["evt_1KkomkBrSjgsps2DGGBtipW4"](https://dashboard.stripe.com/events/evt_1KkomkBrSjgsps2DGGBtipW4),
  "object": "event",
  "api_version": "2020-03-02",
  "created": 1649074409,
  "data": {
    "object": {
      "id": ["in_1KknpoBrSjgsps2DMwiQEzJ9"](https://dashboard.stripe.com/invoices/in_1KknpoBrSjgsps2DMwiQEzJ9),
      "object": "invoice",
      "account_country": "US",
      "account_name": "worknenjoy, Inc.",
      "account_tax_ids": null,
      "amount_due": 37760,
      "amount_paid": 37760,
      "amount_remaining": 0,
      "application_fee_amount": null,
      "attempt_count": 1,
      "attempted": true,
      "auto_advance": false,
      "automatic_tax": {
        "enabled": false,
        "status": null
      },
      "billing_reason": "manual",
      "charge": ["ch_3KknvTBrSjgsps2D036v7gVJ"](https://dashboard.stripe.com/payments/ch_3KknvTBrSjgsps2D036v7gVJ),
      "collection_method": "send_invoice",
      "created": 1649070756,
      "currency": "usd",
      "custom_fields": [
        {
          "name": "task_id",
          "value": "609"
        }
      ],
      "customer": ["cus_J4zTz8uySTkLlL"](https://dashboard.stripe.com/customers/cus_J4zTz8uySTkLlL),
      "customer_address": null,
      "customer_email": "test@fitnowbrasil.com.br",
      "customer_name": "Test",
      "customer_phone": null,
      "customer_shipping": {
        "address": {
          "city": "",
          "country": "",
          "line1": "",
          "line2": "",
          "postal_code": "",
          "state": ""
        },
        "name": "Test",
        "phone": ""
      },
      "customer_tax_exempt": "none",
      "customer_tax_ids": [
      ],
      "default_payment_method": null,
      "default_source": null,
      "default_tax_rates": [
      ],
      "description": "",
      "discount": null,
      "discounts": [
      ],
      "due_date": 1651663107,
      "ending_balance": 0,
      "footer": "Adjustments on the app flow to be approved on Apple Store",
      "hosted_invoice_url": "https://invoice.stripe.com/i/acct_19qSWHBrSjgsps2D/live_YWNjdF8xOXFTV0hCclNqZ3NwczJELF9MUmhFUXc4WkpId3I2cUdMdmRybEJxN1lSZk5SZmpNLDM5NjE1MjEw0200i7wd6fIN?s=ap",
      "invoice_pdf": "https://pay.stripe.com/invoice/acct_19qSWHBrSjgsps2D/live_YWNjdF8xOXFTV0hCclNqZ3NwczJELF9MUmhFUXc4WkpId3I2cUdMdmRybEJxN1lSZk5SZmpNLDM5NjE1MjEw0200i7wd6fIN/pdf?s=ap",
      "last_finalization_error": null,
      "lines": {
        "object": "list",
        "data": [
          {
            "id": ["il_1KknpoBrSjgsps2Difan8czG"](https://dashboard.stripe.com/line_items/il_1KknpoBrSjgsps2Difan8czG),
            "object": "line_item",
            "amount": 37760,
            "currency": "usd",
            "description": "Development service for a task on Gitpay: https://gitpay.me/#/task/609",
            "discount_amounts": [
            ],
            "discountable": true,
            "discounts": [
            ],
            "invoice_item": "ii_1KknpoBrSjgsps2DoUSzJLiO",
            "livemode": true,
            "metadata": {
              "task_id": "609",
              "order_id": "444"
            },
            "period": {
              "end": 1649070756,
              "start": 1649070756
            },
            "plan": null,
            "price": {
              "id": ["price_1KknpgBrSjgsps2DLKbhlCB2"](https://dashboard.stripe.com/prices/price_1KknpgBrSjgsps2DLKbhlCB2),
              "object": "price",
              "active": false,
              "billing_scheme": "per_unit",
              "created": 1649070748,
              "currency": "usd",
              "livemode": true,
              "lookup_key": null,
              "metadata": {
              },
              "nickname": null,
              "product": ["prod_LMRqROwn9P29Dh"](https://dashboard.stripe.com/products/prod_LMRqROwn9P29Dh),
              "recurring": null,
              "tax_behavior": "unspecified",
              "tiers_mode": null,
              "transform_quantity": null,
              "type": "one_time",
              "unit_amount": 37760,
              "unit_amount_decimal": "37760"
            },
            "proration": false,
            "proration_details": {
              "credited_items": null
            },
            "quantity": 1,
            "subscription": null,
            "tax_amounts": [
            ],
            "tax_rates": [
            ],
            "type": "invoiceitem"
          }
        ],
        "has_more": false,
        "total_count": 1,
        "url": "/v1/invoices/in_1KknpoBrSjgsps2DMwiQEzJ9/lines"
      },
      "livemode": true,
      "metadata": {
      },
      "next_payment_attempt": null,
      "number": "USD-0023",
      "on_behalf_of": null,
      "paid": true,
      "paid_out_of_band": false,
      "payment_intent": ["pi_3KknvTBrSjgsps2D0aJYD07Q"](https://dashboard.stripe.com/payments/pi_3KknvTBrSjgsps2D0aJYD07Q),
      "payment_settings": {
        "payment_method_options": null,
        "payment_method_types": null
      },
      "period_end": 1649070748,
      "period_start": 1649070748,
      "post_payment_credit_notes_amount": 0,
      "pre_payment_credit_notes_amount": 0,
      "quote": null,
      "receipt_number": "2145-3666",
      "starting_balance": 0,
      "statement_descriptor": null,
      "status": "paid",
      "status_transitions": {
        "finalized_at": 1649071107,
        "marked_uncollectible_at": null,
        "paid_at": 1649074409,
        "voided_at": null
      },
      "subscription": null,
      "subtotal": 37760,
      "tax": null,
      "tax_percent": null,
      "test_clock": null,
      "total": 37760,
      "total_discount_amounts": [
      ],
      "total_tax_amounts": [
      ],
      "transfer_data": null,
      "webhooks_delivered_at": 1649070757
    }
  },
  "livemode": true,
  "pending_webhooks": 1,
  "request": {
    "id": "req_QIRDAI7gYvjpbj",
    "idempotency_key": "854d1616-b48d-492f-b47e-d5ba5c92595c"
  },
  "type": "invoice.payment_succeeded"
}

we have the task_id and the order id, as payment id to update the order on Gitpay with these data

Please make the automated webhook test based on this webhook to update the payment

The event is invoice.payment_succeeded

alexanmtz commented 2 years ago

UPDATE: @VictorAlessander I've changed the object from my last comment to the right one as you mentioned before