I wan't to capture a new paypal subscription from frontend in my backend and give response with the needed data for mongodb.
If I add a body with capture_type: 'OUTSTANDING_BALANCE' (I found that in the manual) I'm getting this error. So I'm not sure either it's just a wrong body or i totally mess up something else in the backend but so far I can't capture the subscription even so I get a subscription Id from createSubscription Controller
PayPalScriptProvider
<PayPalScriptProvider options={initialOptions}>
<PayPalSubscriptionButton/>
</PayPalScriptProvider>
PayPal Button
{isPending ? <LoadingMedium /> : null}
<PayPalButtons
createSubscription={(data, actions) => {
return axios
.post(
'/api/subscription',
)
.then((response) => {
return response.data.id;
});
}}
onApprove={(data, actions) => {
axios
.post(`/api/subscription/${data.subscriptionID}/capture`)
.then(() => {
axios
.patch(
`/api/activesubscription`,
{
id: activeSub[0]?._id,
subscriptionID: data.subscriptionID,
}
)
});
});
}}
/>
Route for createSubscription
router.route('/subscription').post(async (req, res) => {
const searchPlan = await SubscriptionAmount.find();
console.log(searchPlan[0]?.subscriptionAmount);
const subscription = await paypalFee.createSubscription(
searchPlan[0]?.subscriptionAmount
);
res.json(subscription);
});
Router for onApprove
router.post('/subscription/:subscriptionID/capture', async (req, res) => {
const { subscriptionID } = req.params;
console.log('subscriptionID', subscriptionID);
const captureData = await paypalFee.captureSubscription(subscriptionID);
console.log('captureData', captureData);
res.json(captureData);
});
createSubscription Controller
async function createSubscription(planId) {
const accessToken = await generateAccessToken();
const url = `${base}/v1/billing/subscriptions`;
const response = await fetch(url, {
method: 'post',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${accessToken}`,
},
body: JSON.stringify({
intent: 'subscription',
plan_id: planId,
}),
});
const data = await response.json();
console.log('data', data);
return data;
}
captureSubscription Controller
async function captureSubscription(subscriptionId) {
const accessToken = await generateAccessToken();
const url = `${base}/v1/billing/subscriptions/${subscriptionId}/capture`;
const response = await fetch(url, {
method: 'post',
body: JSON.stringify({
// capture_type: 'OUTSTANDING_BALANCE',
}),
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${accessToken}`,
},
});
const data = await response.json();
console.log('data', data);
return data;
}
I'm getting this logs for my data in captureSubscription if I do not pass a body in my captureSubscription Controller:
captureData {
name: 'INVALID_REQUEST',
message: 'Request is not well-formed, syntactically incorrect, or violates schema.',
details: [
{
location: 'body',
issue: 'MISSING_REQUEST_BODY',
description: 'Request body is missing.'
}
]
}
With body I'm getting this error
captureData {
name: 'UNPROCESSABLE_ENTITY',
message: 'The requested action could not be performed, semantically incorrect, or failed business validation.',
details: [
{
issue: 'ZERO_OUTSTANDING_BALANCE',
description: 'Current outstanding balance should be greater than zero.'
}
],
}
CodePudding user response:
ZERO_OUTSTANDING_BALANCE
There is no outstanding balance to capture. An outstanding balance occurs when payments are missed due to failures.
For ordinary (non-outstanding) subscription payments, no captures can be triggered. Subscriptions will capture automatically on the schedule you specify in the plan, that is the point of subscriptions.