index.ts
1 year ago
useDonationAmounts.ts
1 year ago
useDonationRefund.ts
1 year ago
useResendReceipt.tsx
1 year ago
useDonationRefund.ts
85 lines
| 1 | import apiFetch from '@wordpress/api-fetch'; |
| 2 | import { useDispatch } from '@wordpress/data'; |
| 3 | import { __ } from '@wordpress/i18n'; |
| 4 | import { useMemo, useState } from 'react'; |
| 5 | import { Donation } from '../admin/components/types'; |
| 6 | import { getDonationOptionsWindowData } from '../utils'; |
| 7 | |
| 8 | /** |
| 9 | * @since 4.6.0 |
| 10 | */ |
| 11 | const canRefundDonation = (donation: Donation) => { |
| 12 | const { gateways } = getDonationOptionsWindowData(); |
| 13 | |
| 14 | //find the gateway in the gateways array |
| 15 | const gateway = gateways.find((gateway) => gateway.id === donation.gatewayId && gateway.enabled); |
| 16 | |
| 17 | return gateway?.supportsRefund && donation.status === 'publish'; |
| 18 | }; |
| 19 | |
| 20 | /** |
| 21 | * @since 4.6.0 |
| 22 | */ |
| 23 | const isResponseDonation = (response: unknown): response is Donation => { |
| 24 | return typeof response === 'object' && response !== null && 'id' in response; |
| 25 | }; |
| 26 | |
| 27 | |
| 28 | |
| 29 | /** |
| 30 | * @since 4.6.0 |
| 31 | */ |
| 32 | export default function useDonationRefund(donation: Donation) { |
| 33 | const [isRefunding, setIsRefunding] = useState(false); |
| 34 | const [isRefunded, setIsRefunded] = useState(false); |
| 35 | const dispatch = useDispatch('givewp/admin-details-page-notifications'); |
| 36 | const canRefund = useMemo(() => (donation ? canRefundDonation(donation) : false), [donation?.gatewayId, donation?.status]); |
| 37 | const {invalidateResolution, invalidateResolutionForStore} = useDispatch('core'); |
| 38 | |
| 39 | /** |
| 40 | * TODO: This is a temporary solution to invalidate the donation cache. |
| 41 | * There is most likely a better way to do this. |
| 42 | */ |
| 43 | const invalidateDonationCache = () => { |
| 44 | invalidateResolution('getEntityRecords', ['givewp', 'donation']); |
| 45 | invalidateResolutionForStore(); |
| 46 | }; |
| 47 | |
| 48 | const refund = async () => { |
| 49 | setIsRefunding(true); |
| 50 | const response = await apiFetch({path: `/givewp/v3/donations/${donation.id}/refund`, method: 'POST'}); |
| 51 | |
| 52 | if (isResponseDonation(response) && response.status === 'refunded') { |
| 53 | setIsRefunding(false); |
| 54 | setIsRefunded(true); |
| 55 | |
| 56 | invalidateDonationCache(); |
| 57 | |
| 58 | dispatch.addSnackbarNotice({ |
| 59 | id: 'refund-donation', |
| 60 | content: __('Refund completed successfully', 'give'), |
| 61 | }); |
| 62 | |
| 63 | return response; |
| 64 | } else { |
| 65 | console.error('Failed to refund donation', response); |
| 66 | setIsRefunding(false); |
| 67 | setIsRefunded(false); |
| 68 | |
| 69 | dispatch.addSnackbarNotice({ |
| 70 | id: 'refund-donation', |
| 71 | content: __('Failed to refund donation', 'give'), |
| 72 | }); |
| 73 | |
| 74 | throw new Error('Failed to refund donation'); |
| 75 | } |
| 76 | }; |
| 77 | |
| 78 | return { |
| 79 | isRefunding, |
| 80 | refund, |
| 81 | isRefunded, |
| 82 | canRefund, |
| 83 | }; |
| 84 | } |
| 85 |