MetalAPI
XAU3.997,89−1,54 %XAG53,936−1,51 %XPT1.554,47−0,83 %XPD1.047,03−0,44 %XCU6,5080+2,29 %WTI103,27+3,82 %BRENT111,70−1,30 %EUR1,120400−0,01 %GBP1,337500−0,01 %JPY0,0063761+0,14 %CHF1,213445−0,25 %TRY0,020125−0,12 %BTC80.635,16−0,17 %ETH2.353,78−0,09 %
Alle Artikel
GoldPHPWordPressTutorial

Goldpreis-API in PHP: cURL, Guzzle und ein WordPress-Shortcode

Goldpreis-API in PHP mit cURL oder Guzzle nutzen und in WordPress einen gecachten [gold_price]-Shortcode mit Transients und WP-Cron einbauen – oder ein Widget.

Von MetalAPI Team··7 Min. Lesezeit

Goldpreis-API in PHP: die Grundlagen

Eine Goldpreis-API liefert Ihrem PHP-Code den aktuellen Goldpreis als JSON, etwa für Produktpreise, eine Preiszeile im Theme oder einen täglichen Bericht. Dieses Tutorial behandelt reines PHP mit cURL, den HTTP-Client Guzzle und WordPress, wo ein gecachter [gold_price]-Shortcode, den WP-Cron aktualisiert, den Preis in jeden Beitrag und jede Seite bringt. Es verwendet MetalAPI, eine JSON-REST-API für Edelmetalle, Industriemetalle, Energie, Währungen und Krypto.

Sie benötigen einen API-Schlüssel aus dem MetalAPI-Dashboard. Schlüssel beginnen mit mk_live_, und der Free-Tarif umfasst 100 Anfragen pro Monat mit täglicher Preisaktualisierung, ohne Kreditkarte. Halten Sie den Schlüssel aus Ihrem Code heraus: in einer Umgebungsvariablen bei reinem PHP oder in wp-config.php bei WordPress.

Jeder Endpunkt ist eine GET-Anfrage unter https://metalapi.com/api/v1. Senden Sie den Schlüssel im Header X-API-Key (oder als Authorization: Bearer) statt im Query-Parameter api_key, damit er nicht in Zugriffsprotokollen landet. Eine Antwort von /latest mit den Beispielwerten der Dokumentation:

GET /api/v1/latest?base=USD&currencies=XAU,EUR
{
  "success": true,
  "timestamp": 1792834892,
  "date": "2026-10-24",
  "base": "USD",
  "rates": {
    "XAU": 0.0002501319,
    "USDXAU": 3997.89,
    "EUR": 0.8925,
    "USDEUR": 1.1204
  },
  "rate_limit": { "...": "..." }
}

rates.USDXAU ist der Preis einer Feinunze Gold in Dollar; rates.XAU ist der Kehrwert, also Unzen pro Dollar. Zeigen Sie diesen Wert daher nie als Preis an. rates.USDEUR ist der Preis eines Euro in Dollar, den das WordPress-Plugin zur Umrechnung verwendet. timestamp ist der Zeitpunkt der Preisdaten in Unix-Sekunden.

So rufen Sie den Goldpreis in PHP mit cURL ab

Die cURL-Erweiterung ist in fast jeder PHP-Installation enthalten. Diese Funktion sendet den Schlüssel in einem Header, setzt Timeouts und wandelt Netzwerk- und API-Fehler in Exceptions um:

gold.php
<?php
// PHP 8+ mit der curl-Erweiterung. Ausführen: METALAPI_KEY=mk_live_... php gold.php
function metalapi(string $path, array $params = []): array
{
    $ch = curl_init('https://metalapi.com/api/v1/' . $path . '?' . http_build_query($params));
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_CONNECTTIMEOUT => 5,
        CURLOPT_TIMEOUT        => 10,
        CURLOPT_HTTPHEADER     => ['X-API-Key: ' . getenv('METALAPI_KEY')],
    ]);
    $body = curl_exec($ch);
    if ($body === false) {
        throw new RuntimeException('Network error: ' . curl_error($ch));
    }
    $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
    $data = json_decode($body, true);
    if (empty($data['success'])) {
        $code = $data['error']['code'] ?? $status;
        $info = $data['error']['info'] ?? "HTTP $status";
        throw new RuntimeException("MetalAPI $code: $info", $code);
    }
    return $data;
}

$data = metalapi('latest', ['base' => 'USD', 'currencies' => 'XAU']);
printf("Gold: %.2f USD per troy oz\n", $data['rates']['USDXAU']);
printf("Time: %s UTC\n", gmdate('Y-m-d H:i', $data['timestamp']));

Mit den Beispielwerten gibt es Gold: 3997.89 USD per troy oz aus. Der Exception-Code ist der Fehlercode von MetalAPI: Wiederholen Sie 104 (das Limit pro Minute) nach den in Retry-After angegebenen Sekunden und 500 oder 503 mit Backoff, beheben Sie aber die Ursache bei Codes wie 102 (ungültiger Schlüssel), 105 (Monatskontingent aufgebraucht) oder 106 (Endpunkt nicht in Ihrem Tarif). Die Anleitung zur Fehlerbehandlung listet alle Codes auf.

Guzzle statt cURL verwenden

In einem Composer-Projekt erledigt Guzzle dasselbe mit weniger Zeilen. Behalten Sie den abschließenden Schrägstrich in base_uri bei und fordern Sie relative Pfade wie latest an, denn Guzzle löst /latest relativ zur Wurzel der Domain auf. Schalten Sie außerdem http_errors ab, damit Fehlerantworten den JSON-Body von MetalAPI liefern, statt eine Exception auszulösen:

gold-guzzle.php
<?php
// composer require guzzlehttp/guzzle
require __DIR__ . '/vendor/autoload.php';

$client = new GuzzleHttp\Client([
    'base_uri'    => 'https://metalapi.com/api/v1/',
    'timeout'     => 10,
    'http_errors' => false,
    'headers'     => ['X-API-Key' => (string) getenv('METALAPI_KEY')],
]);

$res  = $client->get('latest', ['query' => ['base' => 'EUR', 'currencies' => 'XAU', 'unit' => 'gram']]);
$data = json_decode((string) $res->getBody(), true);

if (empty($data['success'])) {
    $code = $data['error']['code'] ?? $res->getStatusCode();
    throw new RuntimeException("MetalAPI $code: " . ($data['error']['info'] ?? $res->getReasonPhrase()), $code);
}
printf("Gold: %.2f EUR per gram\n", $data['rates']['EURXAU']);

Timeouts und andere Netzwerkfehler lösen weiterhin eine ConnectException aus. Fangen Sie sie daher überall dort ab, wo ein Fehler die Seite nicht lahmlegen darf.

Goldpreis in WordPress: ein gecachter [gold_price]-Shortcode

Innerhalb von WordPress verwenden Sie stattdessen wp_remote_get() aus der integrierten HTTP-API. Zwei Designregeln halten den Shortcode schnell und günstig:

  • Die API nicht beim Rendern einer Seite aufrufen. Das Plugin hält die Preise in einem Transient, den WP-Cron im Hintergrund aktualisiert. Besucher lösen nur dann eine Anfrage aus, wenn der Transient fehlt, etwa direkt nach der Aktivierung.
  • Alle Währungen in einem Aufruf abfragen. Mit der Basis USD und currencies=XAU,EUR,GBP enthält die Antwort den Dollarpreis von Gold und von jeder Währung aus demselben Snapshot. Gold in Euro ist also USDXAU ÷ USDEUR, und Gramm ergeben sich aus 31,1034768 Gramm pro Feinunze. Eine Anfrage pro Aktualisierung deckt alle Währungen und Einheiten ab.

Transients können vor ihrem Ablauf verschwinden, etwa wenn ein persistenter Objekt-Cache sie verdrängt. Das Plugin speichert die letzten gültigen Preise deshalb zusätzlich in einer Option. Schlägt eine Aktualisierung fehl, protokolliert es den Fehler und liefert fünf Minuten lang diese Kopie aus. Tragen Sie zuerst den Schlüssel in wp-config.php ein, oberhalb der Zeile, ab der die Datei nicht mehr bearbeitet werden soll:

wp-config.php
define( 'METALAPI_KEY', 'mk_live_your_key_here' );

Speichern Sie dann das Plugin als wp-content/plugins/metalapi-gold-price/metalapi-gold-price.php und aktivieren Sie es unter Plugins:

metalapi-gold-price.php
<?php
/**
 * Plugin Name:  MetalAPI Gold Price
 * Description:  [gold_price] shortcode, cached in a transient and refreshed by WP-Cron.
 * Requires PHP: 8.0
 */
defined( 'ABSPATH' ) || exit;

const MGP_INTERVAL   = 600;              // Sekunden. Standard: 600, Lite: 3600, Free: 86400
const MGP_CURRENCIES = [ 'EUR', 'GBP' ]; // neben USD jede Währung, die Ihre Shortcodes verwenden
const MGP_GRAMS      = [ 'troy_oz' => 31.1034768, 'gram' => 1, 'kilogram' => 1000 ];

function mgp_refresh(): ?array {
    if ( ! defined( 'METALAPI_KEY' ) ) {
        return null;
    }
    $url  = add_query_arg(
        [ 'base' => 'USD', 'currencies' => implode( ',', [ 'XAU', ...MGP_CURRENCIES ] ) ],
        'https://metalapi.com/api/v1/latest'
    );
    $res  = wp_remote_get( $url, [ 'timeout' => 8, 'headers' => [ 'X-API-Key' => METALAPI_KEY ] ] );
    $data = is_wp_error( $res ) ? null : json_decode( wp_remote_retrieve_body( $res ), true );

    if ( empty( $data['success'] ) ) {
        error_log( 'MetalAPI refresh failed: ' . ( is_wp_error( $res ) ? $res->get_error_message() : wp_remote_retrieve_body( $res ) ) );
        $last = get_option( 'mgp_prices_last' );
        if ( $last ) {
            set_transient( 'mgp_prices', $last, 5 * MINUTE_IN_SECONDS ); // pausieren, letzte gültige Preise behalten
        }
        return $last ?: null;
    }

    $per_oz = [ 'USD' => $data['rates']['USDXAU'] ];
    foreach ( MGP_CURRENCIES as $cur ) {
        if ( ! empty( $data['rates'][ "USD$cur" ] ) ) {
            $per_oz[ $cur ] = $data['rates']['USDXAU'] / $data['rates'][ "USD$cur" ];
        }
    }
    $prices = [ 'per_oz' => $per_oz, 'time' => $data['timestamp'] ];
    set_transient( 'mgp_prices', $prices, 2 * MGP_INTERVAL ); // übersteht einen verspäteten Cron-Lauf
    update_option( 'mgp_prices_last', $prices, false );       // Fallback, falls der Transient verdrängt wird
    return $prices;
}

function mgp_prices(): ?array {
    return get_transient( 'mgp_prices' ) ?: mgp_refresh();
}

add_shortcode( 'gold_price', function ( $atts ): string {
    $a    = shortcode_atts( [ 'currency' => 'USD', 'unit' => 'troy_oz', 'decimals' => 2 ], $atts, 'gold_price' );
    $cur  = strtoupper( $a['currency'] );
    $unit = strtolower( $a['unit'] );
    $p    = mgp_prices();
    if ( ! $p || ! isset( $p['per_oz'][ $cur ] ) || ! array_key_exists( $unit, MGP_GRAMS ) ) {
        return '';
    }
    $price = $p['per_oz'][ $cur ] / MGP_GRAMS['troy_oz'] * MGP_GRAMS[ $unit ];
    return sprintf(
        '<span class="gold-price">%s %s / %s</span> <small>%s</small>',
        esc_html( number_format_i18n( $price, absint( $a['decimals'] ) ) ),
        esc_html( $cur ),
        esc_html( str_replace( '_', ' ', $unit ) ),
        esc_html( wp_date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $p['time'] ) )
    );
} );

// WP-Cron: einmal pro Intervall im Hintergrund aktualisieren.
add_filter( 'cron_schedules', function ( array $schedules ): array {
    $schedules['mgp_interval'] = [ 'interval' => MGP_INTERVAL, 'display' => 'MetalAPI refresh' ];
    return $schedules;
} );
add_action( 'mgp_refresh_event', 'mgp_refresh' );

register_activation_hook( __FILE__, function (): void {
    if ( ! wp_next_scheduled( 'mgp_refresh_event' ) ) {
        wp_schedule_event( time(), 'mgp_interval', 'mgp_refresh_event' );
    }
} );
register_deactivation_hook( __FILE__, function (): void {
    wp_clear_scheduled_hook( 'mgp_refresh_event' );
} );

Verwenden Sie ihn in jedem Beitrag, auf jeder Seite oder in einem Shortcode-Block als [gold_price] oder [gold_price currency="EUR" unit="gram"]. Mit den Beispielkursen zeigt der zweite 114,72 EUR / gram an: 3.997,89 ÷ 1,1204 ergibt 3.568,27 Euro pro Feinunze, und geteilt durch 31,1034768 ergibt sich der Grammpreis. Eine Währung, die in MGP_CURRENCIES fehlt, gibt nichts aus. Führen Sie dort also jede Währung auf, die Ihre Shortcodes verwenden.

Goldpreise mit WP-Cron aktualisieren

Der Aktivierungs-Hook plant die Aktualisierung mit dem eigenen Intervall, das über cron_schedules registriert wird, und die Deaktivierung entfernt sie wieder. Setzen Sie MGP_INTERVAL auf das Aktualisierungsintervall Ihres Tarifs oder länger, wenn das Kontingent es erfordert:

TarifMGP_INTERVALAnfragen in einem Monat mit 31 TagenMonatskontingent
Free (tägliche Aktualisierung)8640031100
Lite (Aktualisierung alle 30 Minuten)36007441.000
Standard (Aktualisierung alle 10 Minuten)6004.46410.000

WP-Cron ist kein echter Scheduler: Es führt fällige Ereignisse aus, wenn jemand die Website besucht. Auf einer wenig besuchten Website kann eine Aktualisierung daher verspätet sein; die doppelte Lebensdauer des Transients und die gespeicherte Kopie fangen das ab. Für exaktes Timing ergänzen Sie define( 'DISABLE_WP_CRON', true ); in wp-config.php und führen fällige Ereignisse per WP-CLI aus dem System-Cron aus:

crontab
*/10 * * * * cd /var/www/html && wp cron event run --due-now > /dev/null 2>&1

Denken Sie auch an Seiten-Caching: Ein Full-Page-Cache speichert die Ausgabe des Shortcodes zusammen mit der Seite, Besucher sehen also den Preis vom Zeitpunkt des Cachens. Halten Sie die Cache-Lebensdauer von Preisseiten höchstens so lang wie Ihr Aktualisierungsintervall.

Wann ein Widget ohne Code die bessere Wahl ist

Der Shortcode ist das richtige Werkzeug, wenn der Preis Teil Ihres HTML sein muss oder PHP die Zahl benötigt, etwa um Produkte neu zu bepreisen. Wenn Sie Preise nur anzeigen möchten, ist ein MetalAPI-Widget einfacher:

  • Kein API-Schlüssel und kein PHP. Sie erstellen das Widget im Dashboard und fügen seinen Einbettungscode in einen Block Individuelles HTML (Custom HTML) ein. Spätere Änderungen an Symbolen oder Layout erfordern keine Bearbeitung Ihrer Website.
  • Kein Kontingentverbrauch. Seitenaufrufe von Widgets verbrauchen keine Ihrer monatlichen Anfragen, und jeder Tarif enthält Widgets: 1 im Free-Tarif, 3 im Lite-Tarif und 10 im Standard-Tarif.
  • Sicher mit Seiten-Caching. Die Preise werden in einem iframe geladen, eine gecachte Seite friert sie also nie ein.
Einbettungscode des Widgets
<div id="metalapi-widget-w_abc123"></div>
<script src="https://metalapi.com/js/widget.js" data-widget="w_abc123" async></script>

Wenn Ihr Hoster <script>-Tags entfernt, verwenden Sie die iframe-Variante des Einbettungscodes. So binden Sie ein Live-Goldpreis-Widget ein behandelt den Widget-Builder, die Platzierung in WordPress und die Tariflimits; die Widget-Seite zeigt die Layouts.

Nächste Schritte

Erstellen Sie ein kostenloses Konto, tragen Sie Ihren Schlüssel in wp-config.php ein und installieren Sie das Plugin mit MGP_INTERVAL auf 86400: Eine tägliche Aktualisierung verbraucht 31 der 100 monatlichen Anfragen des Free-Tarifs. Wenn Sie aktuellere Preise brauchen, setzen Sie das Intervall auf das Aktualisierungsintervall Ihres neuen Tarifs und vergleichen Sie die Tarife auf der Preisseite. Für Node.js-Backends zeigt Goldpreis-API in JavaScript dieselben Muster mit Express und Next.js.

Häufige Fragen

Wo sollte ich den API-Schlüssel in WordPress speichern?

In wp-config.php als Konstante oder in einer Umgebungsvariablen, die dort gelesen wird. Niemals in Theme-Dateien, die oft in Git landen, und niemals in JavaScript, das jeder Besucher lesen kann. PHP-Anfragen senden keinen Origin- oder Referer-Header, daher funktioniert auch ein domainbeschränkter Schlüssel vom Server aus.

Warum zeigt der Shortcode das ganze Wochenende denselben Goldpreis?

Spot-Gold wird von Freitag 17:00 bis Sonntag 17:00 New Yorker Zeit nicht gehandelt, daher liefert die API bis zur Wiedereröffnung der Märkte den letzten Preis. Im Free-Tarif ändern sich die Preise außerdem nur einmal täglich.

Wie viele API-Anfragen verbraucht das Plugin?

Eine pro Aktualisierung, ganz gleich, wie viele Besucher, Seiten oder Shortcodes Sie haben, denn ein Aufruf liefert alle Währungen, und Einheiten werden lokal umgerechnet: etwa 4.500 im Monat bei einem Intervall von 10 Minuten.

Kann ich den Goldpreis für WooCommerce-Produktpreise verwenden?

Ja. Rufen Sie mgp_prices() aus PHP auf, zum Beispiel in einem Filter für woocommerce_product_get_price, und multiplizieren Sie den Preis pro Gramm mit Gewicht und Feingehalt des Produkts. Speichern Sie den verwendeten Goldpreis mit jeder Bestellung, damit sich Rechnungen später nicht ändern.

Brauche ich cURL oder Guzzle in WordPress?

Nein. wp_remote_get() nutzt die HTTP-API von WordPress, die einen verfügbaren Transport auswählt und Proxy-Einstellungen berücksichtigt. Verwenden Sie cURL oder Guzzle für reines PHP und für Frameworks wie Laravel oder Symfony.

Probieren Sie es mit Ihren eigenen Daten aus

Erstellen Sie ein kostenloses Konto und senden Sie Ihre erste Anfrage in unter zwei Minuten. 100 Anfragen pro Monat, keine Kreditkarte.

Weiterlesen