Rest API

Hallo Shopware Community und Frohes neues Jahr,

habe mich nun dazu entschieden einen Account zu erstellen, da ich nicht wirklich weiter komme.

Zu meinem Problem, mit der _saleschannel-api _kann ich Problemlos neue Customer erstellen, nur wieso nicht mit der Admin API?

 

Diesen Body schicken ich wenn ich die saleschannel-api benutze. Klappt auch wunderbar und der Account wird erstellt.

$newCustomer = $sales->createCustomer(
    [
// 'groupId' => 'cfbd5018d38d41d8adca10d94fc8bdd6', // Standard-Kundengruppe
// 'defaultPaymentMethodId' => '8d32ff2da5494c75b9ced88aac3a0222', // Lastschrift
// 'salesChannelId' => 'ef4f7ae476e24242b61bf37dc5f7f811', // Testshop
// 'salutationId' => '5c0139b0b67e4b799c81eba1c0a3588c',
// 'customerNumber' => '10000',
        'email' => 'mail1@provider.de',
        'firstName' => 'Test',
        'lastName' => 'Tester',
        'guest' => true, // 'password' => 'UNSECURE_PASSWORD' // Only required when guest is false
        'billingAddress' => [
            'street' => 'Meine Straße',
            'zipcode' => '81723',
            'city' => 'Stadt',
            'countryId' => 'd0de840d55194d3d8f9a7ee89fe85264',
        ]
    ]
);

Bei der Admin API habe ich nun anhand von Debugging und Swagger raus gefunden welche ID’s ich wie bekomme und benutze. Siehe Code oben auskommentiert.

Dennoch bräuchte ich wenn ich die Admin API benutzen möchte die defaultShippingAddressID sowie defaultBillingAddressID.

 

1 => array:6 [▼
      "code" => "c1051bb4-d103-4f74-8988-acbcafc7fdc3"
      "status" => "400"
      "detail" => "This value should not be blank."
      "template" => "This value should not be blank."
      "parameters" => array:1 [▶]
      "source" => array:1 [▼
        "pointer" => "/0/defaultShippingAddressId"
      ]
    ]

 

Um diese anzulegen, bräuchte ich laut swagger die CustomerID, die ich nicht habe da ich ein neuen Customer ja nicht anlegen kann?!

Also wie könnte ich das Problem lösen um mit der Admin API einen neuen Customer anlegen zu können.

Schau doch mal in die Browser-Konsole welche Daten der Admin an die Api schickt. Die Administration ist ja selbst nur eine Applikation die mit der API spricht.

@Moritz Naczenski schrieb:

Schau doch mal in die Browser-Konsole welche Daten der Admin an die Api schickt. Die Administration ist ja selbst nur eine Applikation die mit der API spricht.

In der Konsole vom Browser wird nur ausgegeben das ich zur Seite xyz navigiert bin. Wenn es um das Netzwerk-Tab geht bei Chrome ist es ein normaler GET auf die Url. Arbeite mit guzzle und sende die Request.

Kurze Snippets wie ich diese Sende. (natürlich jetzt unformartiert, aus den einzelnen Funktionen rauskopiert)

 

// __construct
$this->restClient = new Client([
            'base_uri' => $this->config['base_uri'],
            'timeout' => 2.0,
            'headers' => ['Content-Type' => 'application/json'],
        ]);

// Trennlinie - getAccess

$body = json_encode([
            'client_id' => $this->config['api-secret']['client-id'],
            'client_secret' => $this->config['api-secret']['client-secret'],
            'grant_type' => 'client_credentials'
        ]);

        $response = $this->restClient->post(
            '/api/oauth/token',
            [
                'Content-Type' => 'application/json',
                'body' => $body
            ]
        );

        $body = json_decode($response->getBody()->getContents(), true);
        $this->setAccessData($body);

// Trennlinie - createShopwareApiRequest

return new Request(
            $method,
            $this->config['base_uri'] . '/api/v1/' . $uri,
            [
                'Authorization' => 'Bearer ' . $this->accessToken,
                'Accept' => '*/*',
                'Content-Type' => 'application/json'
            ],
            $body
        );

Sofern was anderes gemeint war mit „Schaue doch mal in die Browser-Konsole welche Daten der Admin an die Api schickt.“, sag mir doch bitte wonach ich schauen sollte. Ich könnte mit xdebug punkt für punkt den request nach gehen, aber das was gesendet wird steht im ersten Post.  Der $newCustomer = $rest->createCustomer ist unten die Funktion.

 

public function createCustomer(array $body)
    {
        return $this->getRestClient()->request(
            'POST',
            'customer',
            $body
        );
    }

 

@CallMeAlex schrieb:

@Moritz Naczenski schrieb:

Schau doch mal in die Browser-Konsole welche Daten der Admin an die Api schickt. Die Administration ist ja selbst nur eine Applikation die mit der API spricht.

In der Konsole vom Browser wird nur ausgegeben das ich zur Seite xyz navigiert bin. Wenn es um das Netzwerk-Tab geht bei Chrome ist es ein normaler GET auf die Url. Arbeite mit guzzle und sende die Request.

Das stimmt so aber nicht.

 

@Moritz Naczenski schrieb:

@CallMeAlex schrieb:

@Moritz Naczenski schrieb:

Schau doch mal in die Browser-Konsole welche Daten der Admin an die Api schickt. Die Administration ist ja selbst nur eine Applikation die mit der API spricht.

In der Konsole vom Browser wird nur ausgegeben das ich zur Seite xyz navigiert bin. Wenn es um das Netzwerk-Tab geht bei Chrome ist es ein normaler GET auf die Url. Arbeite mit guzzle und sende die Request.

Das stimmt so aber nicht.

Ich glaube dann habe ich dich missverstanden. Wenn ich das über das Backend mache und nicht von meiner anderen Seite sieht es so aus wie bei dir auf dem Screenshot.

Vielleicht sollte ich es erwähnen, habe local zwei Docker Container. Auf dem einenm läuft der Shop und von dem anderen senden ich mit meiner Laravel App + Guzzle die Request zu Shopware rüber.

 

 

// Edit.

Wenn ich das rein über API Calls lösen möchte, muss ich doch erst eine Billing/Shipping-Address erstellen, nur wie ich es anhand swagger sehe brauche ich dafür ein Customer. Diesen habe ich in dem Augenblick ja noch nicht, da ich einen erstellen möchte mit den Daten.

Die Administration macht es ja auch über die API, schau es dir da einfach ab. Da kannst du ja auch neue Kunden anlegen mit billing und shipping. Die Daten da im payload sind ja exakt die gleichen, die du auch in Postman senden würdest

@Moritz Naczenski schrieb:

Die Administration macht es ja auch über die API, schau es dir da einfach ab. Da kannst du ja auch neue Kunden anlegen mit billing und shipping. Die Daten da im payload sind ja exakt die gleichen, die du auch in Postman senden würdest

Habe mich jetzt mit dem Request aus dem Backend befasst. (Schon mal interessant um die customerNumber raus zufinden welche frei ist.)

Was ich dennoch nicht verstehe wie ich mit einem 204 Post request an customer direkt schon die defaultBillingAddressId und defaultShippingAddressId hat, obwohl diese eigentlich in diesem Augenblick auch erstellt werden sollten. Also woher er die IDs bezieht, obwohl die ja auch in echtzeit erzeugt werden müssten für den Customer den ich momentan erstelle.

 

Update 12:00~ Uhr

Habe es nun gelöst bekommen.  Für alle die es Interessiert. Die anderen IDs die ich brauchte für Testshop etc. lese ich auch aus der API aus.

try {
            $uuid = Str::uuid()->getHex();
            $newCustomer = $rest->createCustomer(
                [
                    'groupId' => 'cfbd5018d38d41d8adca10d94fc8bdd6', // Standard-Kundengruppe
                    'defaultPaymentMethodId' => '8d32ff2da5494c75b9ced88aac3a0222', // Lastschrift
                    'salesChannelId' => 'ef4f7ae476e24242b61bf37dc5f7f811', // Testshop
                    'salutationId' => '5c0139b0b67e4b799c81eba1c0a3588c', // Herr
                    'customerNumber' => $rest->reserveNextCustomerNumber($salesChannelId),

                    'email' => 'mail01@provider.de',
                    'firstName' => 'Firstname',
                    'lastName' => 'Lastname',
                    'guest' => false, // 'password' => 'UNSECURE_PASSWORD' // Only required when guest is false
                    'password' => 'meinpassword',

                    'defaultBillingAddressId' => $uuid,
                    'defaultShippingAddressId' => $uuid,

                    'addresses' => [
                        0 => [
                            'countryId' => 'd0de840d55194d3d8f9a7ee89fe85264',
                            'salutationId' => '5c0139b0b67e4b799c81eba1c0a3588c',
                            'firstName' => 'Firstname',
                            'lastName' => 'Lastname',
                            'zipcode' => '40000',
                            'city' => 'City',
                            'street' => 'Alexander Straße 1',
                            'id' => $uuid,
                        ]
                    ]
                ]
            );
        } catch (BadResponseException $e) {
            dd(
                json_decode($e->getResponse()->getBody()->getContents(), true)
            );
        }

 

Hallo zusammen! Ich versuche mich bei der neuen Shopware API v6 mit der „Password authentication“ anzumelden, habe das allerdings noch nicht hingekriegt (https://docs.shopware.com/en/shopware-platform-dev-en/api/admin-authentication) . Die „Client credential authentication“, wo ich unter Settings/Integrations einen Zugang mache und mich damit anmelde, funktioniert tadellos. Ich habe angenommen, dass man sich mit „Password authentication“ mit den Credentials des jeweiligen Users an der API anmelden kann… Könnte mir bitte jemand mal erklären, ob das überhaupt so funktioniert, und wenn ja wie? Vielen Dank!

@roger schrieb:

Hallo zusammen! Ich versuche mich bei der neuen Shopware API v6 mit der „Password authentication“ anzumelden, habe das allerdings noch nicht hingekriegt (https://docs.shopware.com/en/shopware-platform-dev-en/api/admin-authentication) . Die „Client credential authentication“, wo ich unter Settings/Integrations einen Zugang mache und mich damit anmelde, funktioniert tadellos. Ich habe angenommen, dass man sich mit „Password authentication“ mit den Credentials des jeweiligen Users an der API anmelden kann… Könnte mir bitte jemand mal erklären, ob das überhaupt so funktioniert, und wenn ja wie? Vielen Dank!

Also du holst dir erst über eine Route den Bearer-Token: Home | Shopware Documentation

Danach sendest du jeweils diesen Token mit. 

Hi Moritz! das geht also nur mit der client-credential-authentication? das habe ich wie gesagt schon…

Was ich möchte, ist die Authentifizierung mit dem Zugangsschlüssel vom User (Benutzerprofil, ganz unten) und dann auch mit Password-Autentication

Oder ist das gar nicht möglich?

Oder meinst du das selbe?;)) 

danke

 

@roger schrieb:

Hi Moritz! das geht also nur mit der client-credential-authentication? das habe ich wie gesagt schon…

Was ich möchte, ist die Authentifizierung mit dem Zugangsschlüssel vom User (Benutzerprofil, ganz unten) und dann auch mit Password-Autentication

Oder ist das gar nicht möglich?

Oder meinst du das selbe?;)) 

danke

 

Bin zwar nicht Moritz, aber es gibt 2x Möglichkeiten sich einzuloggen. Mit der client-id und client-secret (api) oder wie du meintest mit dem Benutzernamen, Passwort und einem sales-channel-api (key).

 

Sofern du da weitere Informationen bräuchtest, sag bescheid. Habe soweit beides in meinem API Connector geschrieben, aber ich force die zweite Möglichkeit raus, da ich nicht möchte das man mit E-Mails und Passwörten rumhantiert.

 

Grüße 

@CallMeAlex schrieb:

@Moritz Naczenski wrote:

The administration also does it via the API, just take a look at it. You can also create new customers with billing and shipping. The data in the payload is exactly the same as you would send it in Postman

I have now dealt with the request from the backend. (Interesting to find out which customerNumber is free.)

However, I don’t understand how I already have the defaultBillingAddressId and defaultShippingAddressId with a 204 post request to customer, although these should actually be created at this moment. So where does he get the IDs from, although they would also have to be generated in real time for the customer I’m currently creating.

 

Update 12:00 p.m.

Got it solved now. For everybody who’s interested. The other IDs I needed for the test shop etc. are also read from the API.

try {
            $uuid = Str::uuid()->getHex();
            $newCustomer = $rest->createCustomer(
                [
                    'groupId' => 'cfbd5018d38d41d8adca10d94fc8bdd6', // Standard-Kundengruppe
                    'defaultPaymentMethodId' => '8d32ff2da5494c75b9ced88aac3a0222', // Lastschrift
                    'salesChannelId' => 'ef4f7ae476e24242b61bf37dc5f7f811', // Testshop
                    'salutationId' => '5c0139b0b67e4b799c81eba1c0a3588c', // Herr
                    'customerNumber' => $rest->reserveNextCustomerNumber($salesChannelId),

                    'email' => 'mail01@provider.de',
                    'firstName' => 'Firstname',
                    'lastName' => 'Lastname',
                    'guest' => false, // 'password' => 'UNSECURE_PASSWORD' // Only required when guest is false
                    'password' => 'meinpassword',

                    'defaultBillingAddressId' => $uuid,
                    'defaultShippingAddressId' => $uuid,

                    'addresses' => [
                        0 => [
                            'countryId' => 'd0de840d55194d3d8f9a7ee89fe85264',
                            'salutationId' => '5c0139b0b67e4b799c81eba1c0a3588c',
                            'firstName' => 'Firstname',
                            'lastName' => 'Lastname',
                            'zipcode' => '40000',
                            'city' => 'City',
                            'street' => 'Alexander Straße 1',
                            'id' => $uuid,
                        ]
                    ]
                ]
            );
        } catch (BadResponseException $e) {
            dd(
                json_decode($e->getResponse()->getBody()->getContents(), true)
            );
        }

 

 

Hi you have mentioned this method $uuid = Str::uuid()->getHex();

Are you consuming API here to get new uuid or using some own method to generate uuid?

@imranbajwa schrieb:

@CallMeAlex schrieb:

@Moritz Naczenski wrote:

The administration also does it via the API, just take a look at it. You can also create new customers with billing and shipping. The data in the payload is exactly the same as you would send it in Postman

I have now dealt with the request from the backend. (Interesting to find out which customerNumber is free.)

However, I don’t understand how I already have the defaultBillingAddressId and defaultShippingAddressId with a 204 post request to customer, although these should actually be created at this moment. So where does he get the IDs from, although they would also have to be generated in real time for the customer I’m currently creating.

 

Update 12:00 p.m.

Got it solved now. For everybody who’s interested. The other IDs I needed for the test shop etc. are also read from the API.

try {
$uuid = Str::uuid()->getHex();
$newCustomer = $rest->createCustomer(
[
‚groupId‘ => ‚cfbd5018d38d41d8adca10d94fc8bdd6‘, // Standard-Kundengruppe
‚defaultPaymentMethodId‘ => ‚8d32ff2da5494c75b9ced88aac3a0222‘, // Lastschrift
‚salesChannelId‘ => ‚ef4f7ae476e24242b61bf37dc5f7f811‘, // Testshop
‚salutationId‘ => ‚5c0139b0b67e4b799c81eba1c0a3588c‘, // Herr
‚customerNumber‘ => $rest->reserveNextCustomerNumber($salesChannelId),

‚email‘ => ‚mail01@provider.de‘,
‚firstName‘ => ‚Firstname‘,
‚lastName‘ => ‚Lastname‘,
‚guest‘ => false, // ‚password‘ => ‚UNSECURE_PASSWORD‘ // Only required when guest is false
‚password‘ => ‚meinpassword‘,

‚defaultBillingAddressId‘ => $uuid,
‚defaultShippingAddressId‘ => $uuid,

‚addresses‘ => [
0 => [
‚countryId‘ => ‚d0de840d55194d3d8f9a7ee89fe85264‘,
‚salutationId‘ => ‚5c0139b0b67e4b799c81eba1c0a3588c‘,
‚firstName‘ => ‚Firstname‘,
‚lastName‘ => ‚Lastname‘,
‚zipcode‘ => ‚40000‘,
‚city‘ => ‚City‘,
‚street‘ => ‚Alexander Straße 1‘,
‚id‘ => $uuid,
]
]
]
);
} catch (BadResponseException $e) {
dd(
json_decode($e->getResponse()->getBody()->getContents(), true)
);
}

 

 

Hi you have mentioned this method $uuid = Str::uuid()->getHex();

Are you consuming API here to get new uuid or using some own method to generate uuid?

That Str::uuid()->getHex() is imported by Laravel.

However here is the Function 

https://laravel.com/api/7.x/Illuminate/Support/Str.html#method_uuid Str::uuid()

https://github.com/ramsey/uuid/blob/master/src/Uuid.php#L334-L337 ->getHex()

@CallMeAlex schrieb:

That Str::uuid()->getHex() is imported by Laravel.

However here is the Function 

https://laravel.com/api/7.x/Illuminate/Support/Str.html#method_uuid Str::uuid()

https://github.com/ramsey/uuid/blob/master/src/Uuid.php#L334-L337 ->getHex()

Hallo zusammen, 

bin gerade dran ein Plugin für den Import von Artikeln zu schreiben und hab noch nicht rausgefunden, wie ich die UUID bei eine Artikel-Neuanlage generieren kann.

Könnte ich die Klasse Str einfach in meiner Plugin-Klasse importieren? Was müsste ich da dann schreiben?

Vielen Dank für eure Hilfe,

Tobi