Add paypal-invoices extension#27225
Conversation
- Add metadata screenshots, remove old media files - Fix token cache invalidation, updateDueDate body, and payer-view URL guard
|
Congratulations on your new Raycast extension! 🚀 We're currently experiencing a high volume of incoming requests. As a result, the initial review may take up to 10-15 business days. Once the PR is approved and merged, the extension will be available on our Store. |
Greptile SummaryThis PR adds a new
Confidence Score: 3/5The extension has a validation gap in line-item quantity fields that will cause PayPal API calls to fail with no field-level feedback when the field is cleared or set to non-numeric input. The validate() function in both Create Invoice and Edit Invoice checks name and price but never validates quantity. Submitting an empty or non-numeric quantity sends a malformed body to PayPal, which rejects it; the user only sees a generic toast error with no indication that quantity is the problem. All other previously raised issues appear to have been addressed in this revision. extensions/paypal-invoices/src/create-invoice.tsx and extensions/paypal-invoices/src/my-invoices.tsx — both validate() functions need a quantity check added alongside the existing name/price checks. Important Files Changed
Prompt To Fix All With AIFix the following 2 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 2
extensions/paypal-invoices/src/create-invoice.tsx:244-258
**Quantity field is never validated**
`validate()` checks `name` and `price` but not `quantity`. An empty or non-numeric quantity (e.g. the user clears the field) passes client-side validation, but `buildInvoiceBody` forwards the raw string `quantity: item.quantity` to PayPal. PayPal will reject the request with a 400/422, surfaced only as a generic "Failed to create invoice" toast with no field-level highlight to guide the user. The same gap exists in `EditInvoiceForm.validate()` in `my-invoices.tsx`.
### Issue 2 of 2
extensions/paypal-invoices/src/storage.ts:135-139
**`saveInvoiceDetail` is exported but never imported or called**
The function is defined and exported, but neither `create-invoice.tsx` nor `my-invoices.tsx` imports it. The codebase uses `saveAllInvoiceDetails` for bulk writes and `deleteInvoiceDetail` for cleanup instead. This is dead code that adds confusion about the intended write pattern for invoice details.
Reviews (12): Last reviewed commit: "Update CHANGELOG.md and optimise images" | Re-trigger Greptile |
- Preserve UNPAID status, guard empty invoiceId, check detailResponse.ok - Preserve UNPAID status, guard empty invoiceId, check detailResponse.ok
|
This pull request has been automatically marked as stale because it did not have any recent activity. It will be closed if no further activity occurs in the next 7 days to keep our backlog clean 😊 |
|
I'm not sure if this is the right place to ask, but I wanted to check in on the status of this PR. All 10 automated checks are passing and the extension is ready for review on my end. I noticed raycastbot added a status: stalled label last week. Is there anything I need to do from my side to move this forward, or is it simply waiting in the review queue? I want to make sure I'm not missing any steps. Thanks. |
- Ignore .DS_Store - Fix lint: remove unused imports, apply Prettier formatting - Prefill edit form with existing invoice data, fix loading flash, optimize with local cache
There was a problem hiding this comment.
issue: metadata image style
The current screenshot has local extension icon in the bottom bar
Also, you can use mock data for metadata screenshots
Could you make sure that the metadata images use the same background/appearance as the rest to maintain the same visual expression?
Reference:
0xdhrv
left a comment
There was a problem hiding this comment.
Hey @ethananderstandable 👋
I have added a few comments for you to address.
I'm looking forward to testing this extension again 🔥
Feel free to contact me here or at Slack if you have any questions.
I converted this PR into a draft until it's ready for the review, please press the button Ready for review when it's ready and we'll have a look 😊
- Replace metadata screenshots with clean Window Capture versions - Add development and publishing workflow to README
- Remove .eslintrc.js configuration file - Update .gitignore to include additional files and directories - Upgrade dependencies in package.json and package-lock.json - Modify TypeScript configuration for improved module resolution - Enhance README with clearer instructions and formatting - Update invoice action conditions in my-invoices.tsx for better user experience
|
Want your agent to iterate on Greptile's feedback? Try greploops. |
0xdhrv
left a comment
There was a problem hiding this comment.
Looks good to me, approved ✅
|
Published to the Raycast Store: |
|
🎉 🎉 🎉 We've rewarded your Raycast account with some credits. You will soon be able to exchange them for some swag. |
| } | ||
|
|
||
| async function handleCreateDraftOnly() { | ||
| if (!validate()) return; | ||
| setIsSubmitting(true); | ||
|
|
||
| try { | ||
| await showToast({ style: Toast.Style.Animated, title: "Saving draft…" }); | ||
|
|
||
| const subtotal = calcSubtotal(items); | ||
| const taxAmount = taxPercent | ||
| ? subtotal * (parseFloat(taxPercent) / 100) | ||
| : 0; | ||
| const total = subtotal + taxAmount; | ||
|
|
There was a problem hiding this comment.
Quantity field is never validated
validate() checks name and price but not quantity. An empty or non-numeric quantity (e.g. the user clears the field) passes client-side validation, but buildInvoiceBody forwards the raw string quantity: item.quantity to PayPal. PayPal will reject the request with a 400/422, surfaced only as a generic "Failed to create invoice" toast with no field-level highlight to guide the user. The same gap exists in EditInvoiceForm.validate() in my-invoices.tsx.
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/paypal-invoices/src/create-invoice.tsx
Line: 244-258
Comment:
**Quantity field is never validated**
`validate()` checks `name` and `price` but not `quantity`. An empty or non-numeric quantity (e.g. the user clears the field) passes client-side validation, but `buildInvoiceBody` forwards the raw string `quantity: item.quantity` to PayPal. PayPal will reject the request with a 400/422, surfaced only as a generic "Failed to create invoice" toast with no field-level highlight to guide the user. The same gap exists in `EditInvoiceForm.validate()` in `my-invoices.tsx`.
How can I resolve this? If you propose a fix, please make it concise.
Description
Adds two commands to create and manage PayPal invoices without leaving Raycast.
Create Invoice: fill in customer name (email optional), line items with descriptions, tax name and rate, due date, note to customer, and payment options (tip, partial payment). The default action creates the invoice and copies a shareable payment link to your clipboard. If an email is provided, PayPal also notifies the client directly.
Invoice List: lists all invoices created on this machine, grouped and sorted by your preference (status, recipient, currency, or month). Live status is synced from PayPal on open. Actions per invoice include copying the link, sending to client, editing line items and tax, setting a due date, reviewing in browser, and removing from the local list.
Requires a PayPal REST API Client ID and Secret from developer.paypal.com. A sandbox mode toggle is available in preferences for testing.
Screencast
Checklist
npm run buildand tested this distribution build in Raycastassetsfolder are used by the extension itselfREADMEare placed outside of themetadatafolder