如何在 Stripe 中编写 JavaScript Discoverer Readers?

问题描述 投票:0回答:1

我正在开发 POS 系统,我想连接 Stripe 物理读卡器,而不是模拟读卡器。 这是我的 JavaScript 代码,用于初始化、Redears 发现和连接阅读器。

// Initialize Stripe Terminal
const terminal = StripeTerminal.create({
    onFetchConnectionToken: async () => {
        try {
            const response = await fetch("http://127.0.0.1:8000/create_connection_token/", { method: 'POST' });
            if (!response.ok) {
                throw new Error("Failed to fetch connection token");
            }
            const { secret } = await response.json();
            return secret;
        } catch (error) {
            console.error("Error fetching connection token:", error);
            throw error;
        }
    },
    onUnexpectedReaderDisconnect: () => {
        console.error("Reader unexpectedly disconnected.");
        alert("Le terminal s'est déconnecté de manière inattendue. Veuillez vérifier la connexion et réessayer.");
    },
});

console.log("Stripe Terminal initialized.");

// Discover readers
async function discoverReaders() {
    try {
        console.log("Discovering readers...");

        const config = { 
            simulated: false, 
            location: "LOCATION_ID" 
        };

        const discoverResult = await terminal.discoverReaders(config);
        console.log("Discover Result:", discoverResult);

        if (discoverResult.error) {
            console.error('Error discovering readers:', discoverResult.error.message);
            alert('Erreur lors de la découverte des lecteurs. Vérifiez votre configuration réseau.');
            return null;
        }

        if (discoverResult.discoveredReaders.length === 0) {
            console.warn("No available readers. Ensure the terminal is powered on and connected.");
            alert("Aucun terminal trouvé. Vérifiez la connectivité et la configuration réseau.");
            return null;
        }

        console.log("Discovered readers:", discoverResult.discoveredReaders);
        alert("Lecteurs découverts avec succès.");
        return discoverResult.discoveredReaders[0];
    } catch (error) {
        console.error("Error during reader discovery:", error);
        alert("Une erreur inattendue s'est produite lors de la découverte des lecteurs.");
        return null;
    }
}

// Connect to a reader
async function connectReader(reader) {
    try {
        console.log("Attempting to connect to reader:", reader.label);

        // Connect to the selected reader
        const connectResult = await terminal.connectReader(reader);

        // Handle connection errors
        if (connectResult.error) {
            console.error("Failed to connect:", connectResult.error.message);
            alert(`Connexion échouée : ${connectResult.error.message}`);
            return false;
        }

        console.log("Connected to reader:", connectResult.reader.label);
        alert(`Connecté au lecteur : ${connectResult.reader.label}`);
        return true;
    } catch (error) {
        console.error("Error during reader connection:", error);
        alert("Une erreur inattendue s'est produite lors de la connexion au terminal. Consultez la console pour plus de détails.");
        return false;
    }
}

// Example usage: Discover and connect to a reader
async function handleReaderSetup() {
    const reader = await discoverReaders();
    if (reader) {
        await connectReader(reader);
    }
}

我能够使用 Stripe API 连接阅读器,并且从我的 stripe 中我可以看到阅读器是否在线。 然而,当我运行应用程序并尝试将钱发送给读者进行付款时,它显示Aucun 终端问题。 Vérifiez la connectivité et la configuration réseau。这意味着英文未找到终端。检查连接和网络配置。 令人困惑的是,当我运行此命令时:

import stripe
stripe.api_key = "sk_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

try:
    # List all readers
    readers = stripe.terminal.Reader.list()
    print("Readers:", readers)
except stripe.error.StripeError as e:
    print("Stripe error:", e)
except Exception as e:
    print("An unexpected error occurred:", e)

我得到这个输出:

Readers: {
  "data": [                                                                                                                                                                                                          {                                                                                                                                                                                                                  "action": null,                                                                                                                                                                                                  "device_sw_version": "2.27.7.0",                                                                                                                                                                                 "device_type": "bbpos_wisepos_e",
      "id": "tmr_XXXXXXXXXXXXXX",
      "ip_address": "x.0.0.xxx",
      "label": "Testing_Reader",
      "last_seen_at": 1735518518163,
      "livemode": true,
      "location": "tml_ZZZZZZZZZZZZ",
      "metadata": {},
      "object": "terminal.reader",
      "serial_number": "YYYYYYYYYYYYY",
      "status": "online"
    }
  ],
  "has_more": false,
  "object": "list",
  "url": "/v1/terminal/readers"
}

另外,这个命令:

stripe terminal readers list
显示此结果:

{
  "object": "list",
  "data": [
    {
      "id": "tmr_XXXXXXXXXXXXXX",
      "object": "terminal.reader",
      "action": null,
      "device_sw_version": "2.27.7.0",
      "device_type": "bbpos_wisepos_e",
      "ip_address": "x.0.0.xxx",
      "label": "Testing_Reader",
      "last_seen_at": 1735517252951,
      "livemode": true,
      "location": "tml_ZZZZZZZZZZZZ",
      "metadata": {},
      "serial_number": "YYYYYYYYYYYYY",
      "status": "online"
    }
  ],
  "has_more": false,
  "url": "/v1/terminal/readers"

我真的不明白,为什么要点击这个按钮

<button type="button" id="send-to-terminal" class="btn btn-primary" data-order-id="{{ order.id }}"> Envoyer au terminal</button> gives me the error I mentioned above.

欲了解更多详情,我也有这项服务:

import stripe
import logging
from decimal import Decimal
from django.conf import settings

class PaymentService:
    def __init__(self):
        """Initialize the PaymentService with the Stripe API key."""
        stripe.api_key = settings.STRIPE_SECRET_KEY
        self.logger = logging.getLogger(__name__)

    def get_online_reader(self):
        """
        Fetch the first online terminal reader from Stripe.
        :return: Stripe Terminal Reader object.
        :raises: ValueError if no online reader is found.
        """
        try:
            readers = stripe.terminal.Reader.list(status="online").data
            if not readers:
                self.logger.error("Aucun lecteur de terminal en ligne trouvé.")
                raise ValueError("Aucun lecteur de terminal en ligne trouvé.")
            return readers[0]  # Return the first online reader
        except stripe.error.StripeError as e:
            self.logger.error(f"Erreur Stripe lors de la récupération des lecteurs: {str(e)}")
            raise Exception(f"Erreur Stripe: {str(e)}")

    def create_payment_intent(self, amount, currency="CAD", payment_method_types=None, capture_method="automatic"):
        """
        Create a payment intent for a terminal transaction.
        :param amount: Decimal, total amount to charge.
        :param currency: str, currency code (default: "CAD").
        :param payment_method_types: list, payment methods (default: ["card_present"]).
        :param capture_method: str, capture method for the payment intent.
        :return: Stripe PaymentIntent object.
        """
        try:
            if payment_method_types is None:
                payment_method_types = ["card_present"]

            payment_intent = stripe.PaymentIntent.create(
                amount=int(round(amount, 2) * 100),  # Convert to cents
                currency=currency.lower(),
                payment_method_types=payment_method_types,
                capture_method=capture_method  # Explicitly include this argument
            )
            self.logger.info(f"PaymentIntent created: {payment_intent['id']}")
            return payment_intent
        except stripe.error.StripeError as e:
            self.logger.error(f"Stripe error while creating PaymentIntent: {str(e)}")
            raise Exception(f"Stripe error: {str(e)}")
        except Exception as e:
            self.logger.error(f"Unexpected error while creating PaymentIntent: {str(e)}")
            raise Exception(f"Unexpected error: {str(e)}")

    
    def send_to_terminal(self, payment_intent_id):
        """
        Send a payment intent to the online terminal reader for processing.
        :param payment_intent_id: str, ID of the PaymentIntent.
        :return: Stripe response from the terminal reader.
        """
        try:
            # Retrieve the Reader ID from settings
            reader_id = settings.STRIPE_READER_ID  # Ensure this is correctly set in your configuration
            
            # Send the payment intent to the terminal
            response = stripe.terminal.Reader.process_payment_intent(
                reader_id, {"payment_intent": payment_intent_id}
            )
            
            self.logger.info(f"PaymentIntent {payment_intent_id} sent to reader {reader_id}.")
            return response
        except stripe.error.StripeError as e:
            self.logger.error(f"Erreur Stripe lors de l'envoi au terminal: {str(e)}")
            raise Exception(f"Erreur Stripe: {str(e)}")
        except Exception as e:
            self.logger.error(f"Unexpected error while sending to terminal: {str(e)}")
            raise Exception(f"Unexpected error: {str(e)}")

以及这些观点:

@login_required
def send_to_terminal(request, order_id):
    """
    Send the payment amount to the terminal.
    """
    if request.method == "POST":
        try:
            # Validate amount
            amount = Decimal(request.POST.get('amount', 0))
            if amount <= 0:
                return JsonResponse({'success': False, 'error': 'Montant non valide.'}, status=400)

            # Create PaymentIntent
            payment_intent = stripe.PaymentIntent.create(
                amount=int(amount * 100),
                currency="CAD",
                payment_method_types=["card_present"]
            )

            # List online readers dynamically
            readers = stripe.terminal.Reader.list(status="online").data
            if not readers:
                return JsonResponse({'success': False, 'error': 'Aucun lecteur en ligne trouvé.'}, status=404)

            # Use the first available reader
            reader = readers[0]

            # Send PaymentIntent to the terminal
            response = stripe.terminal.Reader.process_payment_intent(
                reader["id"], {"payment_intent": payment_intent["id"]}
            )

            # Handle the response
            if response.get("status") == "succeeded":
                return JsonResponse({
                    'success': True,
                    'payment_intent_id': payment_intent["id"],
                    'message': 'Paiement envoyé avec succès au terminal.'
                })
            else:
                return JsonResponse({
                    'success': False,
                    'error': response.get("error", "Erreur inconnue du terminal.")
                }, status=400)

        except stripe.error.StripeError as e:
            return JsonResponse({'success': False, 'error': f"Erreur Stripe : {str(e)}"}, status=500)

        except Exception as e:
            return JsonResponse({'success': False, 'error': f"Une erreur inattendue s'est produite: {str(e)}"}, status=500)

    return JsonResponse({'success': False, 'error': 'Méthode non autorisée.'}, status=405)



@csrf_exempt  # Allow requests from the frontend if CSRF tokens are not included
def create_connection_token(request):
    try:
        # Create a connection token
        connection_token = stripe.terminal.ConnectionToken.create()
        return JsonResponse({"secret": connection_token.secret})
    except stripe.error.StripeError as e:
        # Handle Stripe API errors
        return JsonResponse({"error": str(e)}, status=500)
    except Exception as e:
        # Handle other unexpected errors
        return JsonResponse({"error": f"Unexpected error: {str(e)}"}, status=500)
javascript python stripe-payments
1个回答
0
投票

只是想让您知道我已经解决了该问题。这不是与 Stripe 相关的问题,而是与 Reader 本身相关的问题。阅读器在实时模式下运行,但使用的默认 API 密钥是测试 API 密钥。

从这个角度来看,我要检测问题所在并解决它。

[![@csrf_exempt
def create_connection_token(request):
    try:
        print(f"Stripe API Key: {stripe.api_key}")
        connection_token = stripe.terminal.ConnectionToken.create()
        print(f"Generated Connection Token: {connection_token.secret}")
        return JsonResponse({"secret": connection_token.secret})
    except stripe.error.StripeError as e:
        print(f"Stripe error: {e}")
        return JsonResponse({"error": str(e)}, status=500)
    except Exception as e:
        print(f"Unexpected error: {e}")
        return JsonResponse({"error": f"Unexpected error: {str(e)}"}, status=500)][1]][1]

现在我可以将我的 POS 连接到读卡器并将支付金额发送给它。

© www.soinside.com 2019 - 2024. All rights reserved.