Skip to content

Commit c908ac6

Browse files
committed
Add payment logs endpoint and improve CryptAPI callback handling
1 parent 81bf374 commit c908ac6

File tree

4 files changed

+316
-52
lines changed

4 files changed

+316
-52
lines changed

src/routes/index.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ import { htmlToMarkdownRoute } from './html-to-markdown.js';
66
import { markdownToHtmlRoute } from './markdown-to-html.js';
77
import { htmlToEpubRoute } from './html-to-epub.js';
88
import { documentHistoryRoute } from './document-history.js';
9-
import {
10-
subscriptionRoute,
11-
paymentCallbackRoute,
12-
subscriptionStatusRoute
9+
import {
10+
subscriptionRoute,
11+
paymentCallbackRoute,
12+
subscriptionStatusRoute,
13+
paymentLogsRoute
1314
} from './subscription.js';
1415
import { apiKeyRoutes } from './api-keys.js';
1516
import { authMiddleware } from '../middleware/auth-middleware.js';
@@ -38,7 +39,8 @@ protectedRoutes.forEach(route => {
3839
const publicRoutes = [
3940
subscriptionRoute,
4041
paymentCallbackRoute,
41-
subscriptionStatusRoute
42+
subscriptionStatusRoute,
43+
paymentLogsRoute
4244
];
4345

4446
/**

src/routes/subscription.js

Lines changed: 70 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -72,28 +72,48 @@ export async function createSubscriptionHandler(c) {
7272
/**
7373
* Route handler for payment callback
7474
* @param {Object} c - Hono context
75-
* @returns {Response} - JSON response with status
75+
* @returns {Response} - Plain text response with "ok" to acknowledge receipt
7676
*/
7777
export async function paymentCallbackHandler(c) {
7878
try {
79-
const callbackData = await c.req.json();
79+
// Get callback data - could be JSON or query parameters
80+
let callbackData;
81+
const contentType = c.req.header('content-type');
82+
83+
if (contentType && contentType.includes('application/json')) {
84+
callbackData = await c.req.json();
85+
console.log('Payment callback received (JSON):', JSON.stringify(callbackData));
86+
} else {
87+
// Get data from query parameters
88+
const url = new URL(c.req.url);
89+
callbackData = Object.fromEntries(url.searchParams.entries());
90+
console.log('Payment callback received (Query):', JSON.stringify(callbackData));
91+
}
92+
93+
// Log important callback data
94+
console.log(`Payment callback: uuid=${callbackData.uuid}, address_in=${callbackData.address_in}, txid_in=${callbackData.txid_in}`);
95+
console.log(`Payment details: value_coin=${callbackData.value_coin}, pending=${callbackData.pending}, confirmations=${callbackData.confirmations}`);
96+
97+
// Verify the callback signature if provided
98+
const signature = c.req.header('x-ca-signature');
99+
if (signature) {
100+
console.log('Payment callback signature received:', signature);
101+
// TODO: Implement signature verification
102+
}
80103

81104
// Process payment callback
82105
const subscription = await paymentService.processPaymentCallback(callbackData);
106+
console.log(`Payment processed for subscription ${subscription.id}, status: ${subscription.status}`);
83107

84-
// Return success response
85-
return c.json({
86-
status: 'success',
87-
subscription_id: subscription.id,
88-
subscription_status: subscription.status
89-
});
108+
// Return plain text "ok" response as required by CryptAPI
109+
return c.text('*ok*');
90110
} catch (error) {
91111
console.error('Error processing payment callback:', error);
92-
// Always return 200 OK to CryptAPI, even if there's an error
93-
return c.json({
94-
status: 'error',
95-
message: error.message
96-
}, 200);
112+
console.error('Error stack:', error.stack);
113+
114+
// Always return 200 OK with "ok" to CryptAPI, even if there's an error
115+
// This prevents CryptAPI from retrying the callback
116+
return c.text('*ok*');
97117
}
98118
}
99119

@@ -144,6 +164,31 @@ export async function subscriptionStatusHandler(c) {
144164
}
145165
}
146166

167+
/**
168+
* Route handler for checking payment logs
169+
* @param {Object} c - Hono context
170+
* @returns {Response} - JSON response with payment logs
171+
*/
172+
export async function paymentLogsHandler(c) {
173+
try {
174+
const { subscription_id } = await c.req.json();
175+
176+
if (!subscription_id) {
177+
return c.json({ error: 'Subscription ID is required' }, 400);
178+
}
179+
180+
// Get payment logs
181+
const logs = await paymentService.checkPaymentLogs(subscription_id);
182+
183+
return c.json({
184+
subscription_id,
185+
logs
186+
});
187+
} catch (error) {
188+
return errorUtils.handleError(error, c);
189+
}
190+
}
191+
147192
/**
148193
* Route configuration for subscription endpoint
149194
*/
@@ -155,11 +200,11 @@ export const subscriptionRoute = {
155200
};
156201

157202
/**
158-
* Route configuration for payment callback endpoint
203+
* Route configuration for CryptAPI payment callback endpoint
159204
*/
160205
export const paymentCallbackRoute = {
161206
method: 'POST',
162-
path: '/api/1/payment-callback',
207+
path: '/api/1/payments/cryptapi/callback',
163208
middleware: [],
164209
handler: paymentCallbackHandler
165210
};
@@ -172,4 +217,14 @@ export const subscriptionStatusRoute = {
172217
path: '/api/1/subscription-status',
173218
middleware: [],
174219
handler: subscriptionStatusHandler
220+
};
221+
222+
/**
223+
* Route configuration for CryptAPI payment logs endpoint
224+
*/
225+
export const paymentLogsRoute = {
226+
method: 'POST',
227+
path: '/api/1/payments/cryptapi/logs',
228+
middleware: [],
229+
handler: paymentLogsHandler
175230
};

0 commit comments

Comments
 (0)