gitpay icon indicating copy to clipboard operation
gitpay copied to clipboard

Update issue imported from Gitpay after receive an invoice paid webhook

Open alexanmtz opened this issue 3 years ago • 3 comments

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

  • Send notifications
  • Update Payment
  • Display on the issue page
  • Be able to send transfers

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

  • Github API: https://docs.github.com/en/rest
  • Material-UI: https://material-ui.com/

How to reproduce the user scenario

  • Scenario 1
    • Run the project locally
    • Import an issue
    • Emulate a call to our webhooks with the object provided
    • Detect and change payment details

What you will need to complete this issue

Stripe development keys

Tips

  • All the UI will use Material UI (https://material-ui.com/)
  • Use our translation library Run npm run translate on the /frontend folder to sync translation before sending the PR

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 task_id 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

alexanmtz avatar Mar 18 '22 11:03 alexanmtz

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

  • [x] 🔔 Issue open an issue was created
  • [x] 👌 Issue added on Gitpay this issue was added on gitpay https://gitpay.me/#/task/611
  • [ ] 📝 Add bounties A bounty is added to get things done
  • [ ] 📝 Set a deadline A deadline to finish the task (optional)
  • [ ] 💾 Choose a contributor interested You can choose someone interested that will be able to solve your issue

If you want to contribute and be rewarded

  • [ ] 💾 A contributor is interested You can show interest on the task page clicking in "I'm interested"
  • [ ] 💾 You can offer You can make an offer
  • [ ] 🔀 You can be assigned. You can be assigned, you should work on the task and send a Pull Request.
  • [ ] 💬 Review Ask in comments for a review :)
  • [ ] 🏁 Approved Once approved you will receive your payment

📋 Task status

  • [x] OPEN
  • [ ] IN PROGRESS
  • [ ] DONE

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.

GitpayPop avatar Mar 18 '22 15:03 GitpayPop

@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": "[email protected]",
      "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 avatar Apr 04 '22 12:04 alexanmtz

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

alexanmtz avatar Apr 05 '22 10:04 alexanmtz