- Rename function to abstract payment provider details - Add support for both QRIS and PayPal methods - Update frontend to use generic create-payment function - Remove provider-specific naming from UI/UX - Payment provider (Pakasir) is now an implementation detail Response format: - QRIS: returns qr_string for in-app display, payment_url as fallback - PayPal: returns payment_url for redirect 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
132 lines
4.2 KiB
TypeScript
132 lines
4.2 KiB
TypeScript
import { serve } from "https://deno.land/std@0.190.0/http/server.ts";
|
|
|
|
const corsHeaders = {
|
|
"Access-Control-Allow-Origin": "*",
|
|
"Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type",
|
|
};
|
|
|
|
interface CreatePaymentRequest {
|
|
order_id: string;
|
|
amount: number;
|
|
description: string;
|
|
method?: 'qris' | 'paypal';
|
|
}
|
|
|
|
serve(async (req: Request) => {
|
|
// Handle CORS preflight
|
|
if (req.method === "OPTIONS") {
|
|
return new Response(null, { headers: corsHeaders });
|
|
}
|
|
|
|
if (req.method !== "POST") {
|
|
return new Response("Method not allowed", { status: 405, headers: corsHeaders });
|
|
}
|
|
|
|
try {
|
|
const body: CreatePaymentRequest = await req.json();
|
|
const { order_id, amount, description, method = 'qris' } = body;
|
|
|
|
if (!order_id || !amount) {
|
|
return new Response(
|
|
JSON.stringify({ success: false, error: "order_id and amount are required" }),
|
|
{ status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" } }
|
|
);
|
|
}
|
|
|
|
const PAYMENT_PROJECT_SLUG = Deno.env.get("PAKASIR_PROJECT_SLUG") || "";
|
|
const PAYMENT_API_KEY = Deno.env.get("PAKASIR_API_KEY") || "";
|
|
const PAYMENT_CALLBACK_URL = `${Deno.env.get("SUPABASE_URL")}/functions/v1/pakasir-webhook`;
|
|
|
|
if (!PAYMENT_PROJECT_SLUG || !PAYMENT_API_KEY) {
|
|
console.error("[PAYMENT] Missing credentials");
|
|
return new Response(
|
|
JSON.stringify({ success: false, error: "Payment provider credentials not configured" }),
|
|
{ status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" } }
|
|
);
|
|
}
|
|
|
|
console.log("[PAYMENT] Creating payment transaction:", { order_id, amount, method });
|
|
|
|
if (method === 'paypal') {
|
|
// Return PayPal payment URL
|
|
const paypalUrl = `https://app.pakasir.com/paypal/${PAYMENT_PROJECT_SLUG}/${amount}?order_id=${order_id}`;
|
|
|
|
return new Response(
|
|
JSON.stringify({
|
|
success: true,
|
|
data: {
|
|
payment_url: paypalUrl,
|
|
method: 'paypal',
|
|
order_id: order_id,
|
|
}
|
|
}),
|
|
{ headers: { ...corsHeaders, "Content-Type": "application/json" } }
|
|
);
|
|
}
|
|
|
|
// Default: QRIS - Call provider API
|
|
const paymentResponse = await fetch(`https://app.pakasir.com/api/transactioncreate/qris`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
project: PAYMENT_PROJECT_SLUG,
|
|
order_id: order_id,
|
|
amount: amount,
|
|
api_key: PAYMENT_API_KEY,
|
|
description: description || `Order ${order_id}`,
|
|
callback_url: PAYMENT_CALLBACK_URL,
|
|
}),
|
|
});
|
|
|
|
if (!paymentResponse.ok) {
|
|
const errorText = await paymentResponse.text();
|
|
console.error("[PAYMENT] Provider API error:", paymentResponse.status, errorText);
|
|
|
|
// Fallback: return direct payment URL
|
|
const fallbackUrl = `https://app.pakasir.com/pay/${PAYMENT_PROJECT_SLUG}/${amount}?order_id=${order_id}`;
|
|
|
|
return new Response(
|
|
JSON.stringify({
|
|
success: true,
|
|
data: {
|
|
payment_url: fallbackUrl,
|
|
method: 'qris',
|
|
fallback: true,
|
|
order_id: order_id,
|
|
}
|
|
}),
|
|
{ headers: { ...corsHeaders, "Content-Type": "application/json" } }
|
|
);
|
|
}
|
|
|
|
const result = await paymentResponse.json();
|
|
console.log("[PAYMENT] Payment created:", result);
|
|
|
|
// Return QRIS data for display in app
|
|
return new Response(
|
|
JSON.stringify({
|
|
success: true,
|
|
data: {
|
|
method: 'qris',
|
|
qr_string: result.qr_string || result.qr || null,
|
|
expired_at: result.expired_at || null,
|
|
// Fallback URL if QR code is not available
|
|
payment_url: `https://app.pakasir.com/pay/${PAYMENT_PROJECT_SLUG}/${amount}?order_id=${order_id}`,
|
|
order_id: order_id,
|
|
}
|
|
}),
|
|
{ headers: { ...corsHeaders, "Content-Type": "application/json" } }
|
|
);
|
|
|
|
} catch (error: any) {
|
|
console.error("[PAYMENT] Unexpected error:", error);
|
|
return new Response(
|
|
JSON.stringify({
|
|
success: false,
|
|
error: error.message || "Internal server error"
|
|
}),
|
|
{ status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" } }
|
|
);
|
|
}
|
|
});
|