Weiter zum Inhalt
Konto erstellen
oder
anmelden
Das Logo der Stripe-Dokumentation
/
KI fragen
Konto erstellen
Anmelden
Jetzt starten
Zahlungen
Umsatz
Plattformen und Marktplätze
Geldmanagement
Entwicklerressourcen
Übersicht
Umsatzgestaltung
Billing
    Übersicht
    Über die Billing APIs
    Abonnements
    Invoicing
    Nutzungsbasierte Abrechnung
    Connect und Billing
    Tax und Billing
    Angebote
    Umsatzsicherung
    Automatisierungen
    Skripte
      Definition der Skriptsprache
    Umsatzrealisierung
    Kundenverwaltung
    Berechtigungen
    Integration testen
Steuer
Business Analytics
Berichte
Daten
StartseiteUmsatzBillingScripts

Definition der SkriptsprachePrivate Vorschau

Erfahren Sie mehr über die Syntax und Semantik der in Stripe Billing verwendeten Skriptsprache.

Die Skriptsprache von Stripe ist eine Teilmenge von TypeScript. Obwohl die Funktionen von TypeScript beibehalten werden, weist es einige wichtige Unterschiede auf, darunter einen restriktiveren Satz zulässiger Vorgänge. Die Skriptsprache kann dazu beitragen, potenzielle Probleme wie lange Laufzeiten und übermäßigen Speicherverbrauch zu vermeiden.

Syntax

Basistypen und Literale

Die Sprache unterstützt die folgenden primitiven Typen:

// Numeric values let num: number = 42; let pi: number = 3.14159; // Strings let greeting: string = "Hello, world!"; let multiline: string = `This is a multi-line string`; // Booleans let active: boolean = true; let completed: boolean = false; // Null let empty: null = null;

Variablen und Erklärungen

Deklarieren Sie Variablen mit let oder const:

// Variable declarations let count: number = 0; let name: string = "John"; // Constants (must be initialized) const PI: number = 3.14159; const API_KEY: string = "abcd1234";

Typanmerkungen sind optional, werden aber empfohlen:

// Type inferred as number let score = 100; // Explicitly typed let highScore: number = 0;

Funktionen und Lambdas

Definieren Sie Funktionen auf verschiedene Weise:

// Function declaration function add(a: number, b: number): number { return a + b; } // Arrow function (lambda) const multiply = (a: number, b: number): number => { return a * b; }; // Inline arrow function const double = (x: number): number => x * 2;

Objekte und Arrays

Definieren Sie Objekte und Arrays ähnlich wie TypeScript:

// Object literal let person = { name: "Alice", age: 30, address: { city: "Wonderland", zipCode: "12345" } }; // Array literal let numbers = [1, 2, 3, 4, 5]; let names: string[] = ["Alice", "Bob", "Charlie"]; // Array spread let moreNumbers = [...numbers, 6, 7, 8, 9, 10]; // Accessing properties let cityName = person.address.city; let firstNumber = numbers[0];

Ablaufsteuerung

Zu den Ablaufsteuerungsanweisungen gehören if-else-, while- und for-Schleifen:

// If-else statement if (score > 100) { console.log("High score!"); } else if (score > 50) { console.log("Good score!"); } else { console.log("Try again!"); } // While loop let i = 0; while (i < 5) { console.log(i); i++; } // For loop for (let j = 0; j < 5; j++) { console.log(j); }

Break-Anweisungen funktionieren wie erwartet:

// Break in a loop let i = 0; while (true) { if (i >= 5) { break; } i++; }

Operatoren

Nachfolgend finden Sie unterstützte Standardoperatoren:

// Arithmetic operators let sum = 5 + 3; let difference = 10 - 4; let product = 3 * 7; let quotient = 20 / 4; let remainder = 10 % 3; // Modulo // Comparison operators let equal = (5 == 5); let notEqual = (5 != 3); let greater = (10 > 5); let less = (5 < 10); let greaterOrEqual = (5 >= 5); let lessOrEqual = (4 <= 4); // Logical operators let and = (true && false); // false let or = (true || false); // true let not = !true; // false // Compound assignment let value = 5; value += 3; // value is now 8

Import und Export

Organisieren Sie Ihren Code in Modulen:

// Importing modules import { DiscountableItem } from '@stripe/scripts/discounts'; // Export a function export function calculateTotal(items: DiscountableItem[]): number { let sum = 0; for (let i = 0; i < items.length; i++) { sum += items[i].price; } return sum; } // Default export export default function main() { // Main function logic }

Wir unterstützen keine Bibliotheken von Drittanbietern.

Typsystem

Typanmerkungen

Geben Sie Typen nach einem Doppelpunkt an:

let count: number = 0; let name: string = "John"; let active: boolean = true; let items: string[] = ["apple", "banana"];

Schnittstellen und Objekttypen

Definieren Sie Objekttypen inline oder als Schnittstellen:

// Inline object type let person: { name: string; age: number } = { name: "Alice", age: 30 }; // Interface definition interface Product { id: string; name: string; price: number; inStock?: boolean; // Optional property } // Using the interface let laptop: Product = { id: "lt-001", name: "Laptop", price: 999.99, inStock: true };

Unionstypen

Unionstypen ermöglichen es einer Variablen, mehrere Typen zu haben:

// Union type let id: string | number; id = "abc123"; // Valid id = 123; // Also valid

Typerklärungen

Erstellen von Typ-Aliassen:

// Type alias type ID = string | number; // Using the type alias let userId: ID = "user123"; let productId: ID = 456; // Complex type declaration type ApiResponse = { status: number; data: { items: any[]; count: number; }; error?: string; };

Statische Analyse

Unsere Skriptsprache beinhaltet statische Analysen, um sicherzustellen, dass Skripte zuverlässig und effizient sind.

Analyse der Beendigung

Eine wichtige Funktion ist die Beendigungsprüfung, die garantiert, dass Skripte immer beendet werden, wenn Sie sie auf der Infrastruktur von Stripe ausführen, wodurch Endlosschleifen oder Rekursion verhindert werden. Da nicht nachgewiesen werden kann, dass jeder Terminierungscode zur Beendigung führt, lehnen wir einige gültige Programme ab. Im Folgenden finden Sie Tipps zum Schreiben von Skripten zum Beenden.

Der Analyzer verwendet ein Färbesystem:

  • T (Termination – Beendigung): Code, der nachweislich beendet wird.
  • U (Unbekannt): Code, der möglicherweise nicht beendet wird.
// Guaranteed to terminate - marked as T function countdown(n: number): void { while (n > 0) { n = n - 1; // Decreasing counter } } // Not guaranteed to terminate - marked as U function infinite(): void { while (true) { console.log("This runs forever"); } }

Fundierte Rekursion

Der Analyzer prüft, ob rekursive Funktionen ein abnehmendes Maß haben:

// Safe recursion - marked as T function factorial(n: number): number { if (n <= 1) return 1; return n * factorial(n - 1); // n decreases with each call } // Unsafe recursion - marked as U function badRecursion(n: number): number { return badRecursion(n + 1); // n increases, no termination }

Häufige statische Analysemuster

For-Schleifen mit endlichen Grenzen sind sicher:

// Safe loop pattern - marked as T for (let i = 0; i < array.length; i++) { // Loop body with terminating operations }

While-Schleifen erfordern einen abnehmenden Zähler:

// Safe while loop - marked as T let counter = 10; while (counter > 0) { // Do something counter--; // Counter decreases }

Schreiben von beendigungssicherem Code

Befolgen Sie diese Richtlinien, um sicherzustellen, dass Ihr Code die Beendigungsprüfung besteht:

  • Für Schleifen mit klaren, endlichen Grenzen verwenden
  • Stellen Sie sicher, dass while-Schleifen einen abnehmenden Zähler oder eine abnehmende Bedingung haben, die schließlich false wird
  • Aufnahme eines Basisfalls und eines abnehmenden Arguments in rekursive Funktionen
  • Vermeiden Sie komplexe Schleifenbedingungen, wechselseitige Rekursion oder tiefe Verschachtelung von Funktionen und Schleifen
// Good pattern for loops function processItems(items: any[]): void { for (let i = 0; i < items.length; i++) { processItem(items[i]); } }

Laufzeitumgebung

Die Skriptsprache stellt integrierte Objekte bereit, die Sie in Ihren Skripten verwenden können.

Integrierte Objekte

Es stehen mehrere integrierte Objekte zur Verfügung:

Mathematisches Objekt

// Math operations let min = Math.min(5, 3, 7); // 3 let max = Math.max(5, 3, 7); // 7 let floor = Math.floor(3.7); // 3 let ceil = Math.ceil(3.2); // 4

Arrays

// Array creation let numbers = [1, 2, 3, 4, 5]; // Array properties let length = numbers.length; // 5 // Array indexing let firstItem = numbers[0]; // 1 let lastItem = numbers[numbers.length - 1]; // 5 // Array methods let sorted = numbers.sort((a, b) => a - b);

Zeichenfolgenvorgänge

// String concatenation let firstName = "John"; let lastName = "Doe"; let fullName = firstName + " " + lastName; // "John Doe" // String with template literals let greeting = `Hello, ${firstName}!`; // "Hello, John!"

Schemavalidierung

Sie können Ihre Typen mit Anmerkungen versehen, um eine grundlegende Validierung von Feldern bereitzustellen. Verwenden Sie diese Option, wenn Sie das Konfigurationsschema für Ihre Skripts definieren.

Zeichenfolgenvalidierungen

length_validation.ts
/** @minLength 0 @maxLength 10 */ type Greeting = string;
pattern_validation.ts
/** @pattern ^hello world$ */ type Greeting = string;

Validierungen von Zahlen

inclusive_range_validation.ts
/** @minimum 0 @maximum 100 */ type Percent = number;
exclusive_range_validation.ts
/** @exclusiveMinimum -1 @exclusiveMaximum 101 */ type Percent = number;

Array-Validierungen

length_inclusive_validation.ts
/** @minItems 1 @maxItems 5 */ type Names = string[];
uniqueness_validation.ts
/** @uniqueItems */ type Names = string[];

Wenn wir Ihr Anwendungsszenario für die Validierung nicht unterstützen, empfehlen wir, die Validierungsprüfung in Ihre Funktionsdefinition zu integrieren und scripts-preview@stripe.com zu kontaktieren.

Beispiele

Prozentuale Rabattfunktion

Dieses Beispiel zeigt eine Rabattfunktion, die einen prozentualen Rabatt bis zu einem Höchstbetrag gewährt:

max_amount_percent_off.ts
/** * Max Amount Percent Off Discount * * This discount function applies a percentage discount to the gross amount, * but caps the total discount at a maximum amount. It calculates the discount * as a percentage of the gross amount and then ensures it doesn't exceed the * configured maximum. * * Configuration: * - max_amount: The maximum monetary amount that can be discounted * - percent: The percentage discount to apply */ import { MonetaryAmount, Percent } from '@stripe/scripts'; import { DiscountFunction, DiscountableItem, DiscountResult, } from '@stripe/scripts/discounts'; type Configuration = { max_amount: MonetaryAmount; percent: Percent; }; const maxAmountPercentOff: DiscountFunction<Configuration> = ( configuration: Configuration, item: DiscountableItem, ): DiscountResult => { const { max_amount, percent } = configuration; const discount_amount = Math.min(max_amount.amount, item.gross_amount.amount * (percent / 100)); return { discount: { amount: { amount: discount_amount, currency: item.gross_amount.currency, }, status: discount_amount > 0 ? 'APPLIED' : 'NOT_APPLIED', reason: discount_amount > 0 ? 'Discount applied' : 'No discount applied', }, line_item_discounts: [], }; }; export default maxAmountPercentOff;

Gestaffelter Rabatt je nach Menge

Dieses Beispiel zeigt einen Rabatt, für den je nach Menge unterschiedliche Tarife gelten:

tiered_discount.ts
/** * Tiered Discount * * This discount function applies percentage discounts based on quantity tiers. * It sums the quantities across all line items and applies the discount percentage * from the highest applicable tier. The discount is calculated on each line item's * subtotal amount. * * Configuration: * - tiers: Array of objects with minimum_quantity and discount_percent * The tiers are sorted by minimum_quantity in descending order to find * the highest applicable tier. */ import { DiscountFunction, DiscountableItem, DiscountResult, ItemDiscount, } from '@stripe/scripts/discounts'; type Configuration = { tiers: Array<{ minimum_quantity: number; discount_percent: number; }>; }; const tieredDiscount: DiscountFunction<Configuration> = ( configuration: Configuration, item: DiscountableItem, ): DiscountResult => { let discountPercent = 0; let totalQuantity = 0; for (let i = 0; i < item.line_items.length; i++) { totalQuantity += item.line_items[i]?.quantity ?? 0; } const sortedTiers = [...configuration.tiers].sort( (a, b) => b.minimum_quantity - a.minimum_quantity, ); for (let i = 0; i < sortedTiers.length; i++) { const tier = sortedTiers[i]; if (totalQuantity >= tier.minimum_quantity) { discountPercent = tier.discount_percent; break; // Stop after finding the first applicable tier } } let totalDiscountAmount = 0; const lineItemDiscounts: ItemDiscount[] = []; for (let i = 0; i < item.line_items.length; i++) { const lineItem = item.line_items[i]; const lineItemDiscount = lineItem.subtotal.amount * (discountPercent / 100); totalDiscountAmount += lineItemDiscount; lineItemDiscounts.push({ discountable_item_id: lineItem.id, discount: { amount: { amount: lineItemDiscount, currency: lineItem.subtotal.currency, }, status: lineItemDiscount > 0 ? 'APPLIED' : 'NOT_APPLIED', reason: lineItemDiscount > 0 ? `${discountPercent}% tier discount applied` : 'No discount applied', }, }); } return { discount: { amount: { amount: totalDiscountAmount, currency: item.gross_amount.currency, }, status: totalDiscountAmount > 0 ? 'APPLIED' : 'NOT_APPLIED', reason: totalDiscountAmount > 0 ? `${discountPercent}% tier discount applied` : 'No discount applied', }, line_item_discounts: lineItemDiscounts, }; }; export default tieredDiscount;

Tipps zur Fehlerbehebung

Häufige Fehlermuster

Wenn die statische Analyse bei Ihrem Skript fehlschlägt, überprüfen Sie die folgenden häufigen Probleme:

  1. Endlosschleifen: Schleifen ohne klare Beendigungsbedingung

    // Problem: No clear exit condition while (x > 0) { doSomething(); // x never changes } // Fix: Add a decreasing counter while (x > 0) { doSomething(); x--; }
  2. Nicht beendende Rekursion: Rekursive Aufrufe ohne abnehmendes Maß

    // Problem: No decreasing measure function process(data: any): void { process(transformData(data)); } // Fix: Add a depth limit and decreasing measure function process(data: any, depth: number = 10): void { if (depth <= 0) return; process(transformData(data), depth - 1); }
War diese Seite hilfreich?
JaNein
Benötigen Sie Hilfe? Kontaktieren Sie den Kundensupport.
Nehmen Sie an unserem Programm für frühzeitigen Zugriff teil.
Schauen Sie sich unser Änderungsprotokoll an.
Fragen? Sales-Team kontaktieren.
LLM? Lesen Sie llms.txt.
Unterstützt von Markdoc