Failed to publish commerce data LMS

Hi,

I just deployed and configured the eCommerce application using the following guides:

How to Install and Start the E-Commerce Service in Native Installations
Open edX Ecommerce

Everything seems to work properly but when I try to create a new Course in the eCommerce platform, using this guide (https://readthedocs.org/projects/edx-ecommerce/downloads/pdf/latest/) I get the following error:

Failed to publish commerce data for course-v1:csX+CS101x+2020_T1 to LMS

I reviewed the eCommerce log in /edx/var/logs/ecommerce/edx.log and I didn’t find anything meaningful to me. Here is a portion of the log:
Exception: Failed to publish commerce data for course-v1:csX+CS101x+2020_T1 to LMS.
Mar 3 20:05:45 PROD-OpenEDX-VM01 [service_variant=ecommerce][django.request] WARNING [PROD-OpenEDX-VM01 25161] [/edx/app/ecommerce/venvs/ecommerce/local/lib/python2.7/site-packages/django/core/handlers/base.py:152] - Not Found: /api/v2/courses/course-v1:csX+CS101x+2020_T1/
Mar 3 20:05:45 PROD-OpenEDX-VM01 [service_variant=ecommerce][django.request] WARNING [PROD-OpenEDX-VM01 25161] [/edx/app/ecommerce/venvs/ecommerce/local/lib/python2.7/site-packages/django/core/handlers/base.py:152] - Not Found: /api/v2/courses/course-v1:csX+CS101x+2020_T1/
Mar 3 20:05:45 PROD-OpenEDX-VM01 [service_variant=ecommerce][django.request] WARNING [PROD-OpenEDX-VM01 25161] [/edx/app/ecommerce/venvs/ecommerce/local/lib/python2.7/site-packages/django/core/handlers/base.py:152] - Not Found: /api/v2/courses/course-v1:csX+CS101x+2020_T1/
Mar 3 20:07:24 PROD-OpenEDX-VM01 [service_variant=ecommerce][django.request] WARNING [PROD-OpenEDX-VM01 25160] [/edx/app/ecommerce/venvs/ecommerce/local/lib/python2.7/site-packages/django/core/handlers/base.py:152] - Not Found: /api/v2/courses/course-v1:csX+CS101x+2020_T1/
Mar 3 20:07:24 PROD-OpenEDX-VM01 [service_variant=ecommerce][django.request] WARNING [PROD-OpenEDX-VM01 25160] [/edx/app/ecommerce/venvs/ecommerce/local/lib/python2.7/site-packages/django/core/handlers/base.py:152] - Not Found: /api/v2/courses/course-v1:csX+CS101x+2020_T1/
Mar 3 20:07:24 PROD-OpenEDX-VM01 [service_variant=ecommerce][django.request] WARNING [PROD-OpenEDX-VM01 25160] [/edx/app/ecommerce/venvs/ecommerce/local/lib/python2.7/site-packages/django/core/handlers/base.py:152] - Not Found: /api/v2/courses/course-v1:csX+CS101x+2020_T1/
Mar 3 20:07:25 PROD-OpenEDX-VM01 [service_variant=ecommerce][ecommerce.courses.models] INFO [PROD-OpenEDX-VM01 25160] [/edx/app/ecommerce/ecommerce/ecommerce/courses/models.py:212] - Course seat product with certificate type [honor] for [course-v1:csX+CS101x+2020_T1] does not exist. Instantiated a new instance.
Mar 3 20:07:25 PROD-OpenEDX-VM01 [service_variant=ecommerce][ecommerce.courses.models] INFO [PROD-OpenEDX-VM01 25160] [/edx/app/ecommerce/ecommerce/ecommerce/courses/models.py:256] - Course seat product stock record with certificate type [honor] for [course-v1:csX+CS101x+2020_T1] does not exist. Instantiated a new instance.
Mar 3 20:07:25 PROD-OpenEDX-VM01 [service_variant=ecommerce][ecommerce.courses.models] INFO [PROD-OpenEDX-VM01 25160] [/edx/app/ecommerce/ecommerce/ecommerce/courses/models.py:205] - Retrieved course seat child product with certificate type [honor] for [course-v1:csX+CS101x+2020_T1] from database.
Mar 3 20:07:25 PROD-OpenEDX-VM01 [service_variant=ecommerce][ecommerce.courses.models] INFO [PROD-OpenEDX-VM01 25160] [/edx/app/ecommerce/ecommerce/ecommerce/courses/models.py:247] - Retrieved course seat product stock record with certificate type [honor] for [course-v1:csX+CS101x+2020_T1] from database.
Mar 3 20:07:25 PROD-OpenEDX-VM01 [service_variant=ecommerce][ecommerce.courses.publishers] ERROR [PROD-OpenEDX-VM01 25160] [/edx/app/ecommerce/ecommerce/ecommerce/courses/publishers.py:112] - Failed to publish commerce data for [course-v1:csX+CS101x+2020_T1] to LMS.
Traceback (most recent call last):
File “/edx/app/ecommerce/ecommerce/ecommerce/courses/publishers.py”, line 100, in publish
commerce_api_client = site.siteconfiguration.commerce_api_client
File “/edx/app/ecommerce/venvs/ecommerce/local/lib/python2.7/site-packages/django/utils/functional.py”, line 35, in get
res = instance.dict[self.name] = self.func(instance)
File “/edx/app/ecommerce/ecommerce/ecommerce/core/models.py”, line 457, in commerce_api_client
return EdxRestApiClient(self.build_lms_url(’/api/commerce/v1/’), jwt=self.access_token)
File “/edx/app/ecommerce/ecommerce/ecommerce/core/models.py”, line 384, in access_token
token_type=‘jwt’
File “/edx/app/ecommerce/venvs/ecommerce/local/lib/python2.7/site-packages/edx_rest_api_client/client.py”, line 142, in get_oauth_access_token
return get_oauth_access_token(url, client_id, client_secret, token_type=token_type)
File “/edx/app/ecommerce/venvs/ecommerce/local/lib/python2.7/site-packages/edx_rest_api_client/client.py”, line 76, in get_oauth_access_token
data = response.json()
File “/edx/app/ecommerce/venvs/ecommerce/local/lib/python2.7/site-packages/requests/models.py”, line 897, in json
return complexjson.loads(self.text, **kwargs)
File “/edx/app/ecommerce/venvs/ecommerce/local/lib/python2.7/site-packages/simplejson/init.py”, line 518, in loads
return _default_decoder.decode(s)
File “/edx/app/ecommerce/venvs/ecommerce/local/lib/python2.7/site-packages/simplejson/decoder.py”, line 370, in decode
obj, end = self.raw_decode(s)
File “/edx/app/ecommerce/venvs/ecommerce/local/lib/python2.7/site-packages/simplejson/decoder.py”, line 400, in raw_decode
return self.scan_once(s, idx=_w(s, idx).end())
JSONDecodeError: Expecting value: line 9 column 1 (char 8)
Mar 3 20:07:25 PROD-OpenEDX-VM01 [service_variant=ecommerce][ecommerce.extensions.api.serializers] ERROR [PROD-OpenEDX-VM01 25160] [/edx/app/ecommerce/ecommerce/ecommerce/extensions/api/serializers.py:585] - Failed to save and publish [course-v1:csX+CS101x+2020_T1]: [Failed to publish commerce data for course-v1:csX+CS101x+2020_T1 to LMS.]
Traceback (most recent call last):
File “/edx/app/ecommerce/ecommerce/ecommerce/extensions/api/serializers.py”, line 582, in save
raise Exception(resp_message)
Exception: Failed to publish commerce data for course-v1:csX+CS101x+2020_T1 to LMS.

If I try to access directly to https://ecommerce.cs.org/api/v2/courses/course-v1:csX+CS101x+2020_T1/ I get a “Not found error” so I think that the course is never created before to publish to the LMS. The course already exists in the LMS. I get the same result if I try the same process with a new course that does not exist on the LMS.

Any idea about what could be happening here?

Thanks in advance!!

@santifdezmunoz We are two to have the same issue.
I am getting almost the same output as yours in ecommerce logs.

The same will happen when you try to edit an existing course (DemoX) in ecommerce > Course Admin

Same environment : Open edX Native (production).

All I know is there’s an authentication error between ecommerce and LMS.
If you check LMS logs you’d probably get this same error :

2020-03-04 08:34:59,425 ERROR 7728 [django.request] exception.py:135 - Internal Server Error: /oauth2/access_token
Traceback (most recent call last):
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 249, in _legacy_get_response
    response = self._get_response(request)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/django/utils/decorators.py", line 185, in inner
    return func(*args, **kwargs)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/django/views/generic/base.py", line 68, in view
    return self.dispatch(request, *args, **kwargs)
  File "/edx/app/edxapp/edx-platform/openedx/core/djangoapps/oauth_dispatch/views.py", line 100, in dispatch
    response = super(AccessTokenView, self).dispatch(request, *args, **kwargs)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/ratelimit/mixins.py", line 58, in dispatch
    )(super(RatelimitMixin, self).dispatch)(*args, **kwargs)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/ratelimit/decorators.py", line 30, in _wrapped
    return fn(*args, **kw)
  File "/edx/app/edxapp/edx-platform/openedx/core/djangoapps/oauth_dispatch/views.py", line 55, in dispatch
    return view(request, *args, **kwargs)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/django/views/generic/base.py", line 68, in view
    return self.dispatch(request, *args, **kwargs)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/provider/views.py", line 136, in dispatch
    response = super(OAuthView, self).dispatch(request, *args, **kwargs)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/django/views/generic/base.py", line 88, in dispatch
    return handler(request, *args, **kwargs)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/provider/views.py", line 716, in post
    return handler(request, request.POST, client)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/provider/views.py", line 662, in client_credentials
    return self.access_token_response(at)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/provider/views.py", line 583, in access_token_response
    response_data = self.access_token_response_data(access_token, nonce=nonce)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/edx_oauth2_provider/views.py", line 129, in access_token_response_data
    id_token = self.get_id_token(access_token, nonce)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/edx_oauth2_provider/views.py", line 153, in get_id_token
    return oidc.id_token(access_token, nonce, claims_request)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/edx_oauth2_provider/oidc/core.py", line 96, in id_token
    claims_request=claims_request_section,
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/edx_oauth2_provider/oidc/collect.py", line 79, in collect
    values=claims_request or {}
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/edx_oauth2_provider/oidc/collect.py", line 134, in _collect_values
    _visit_handlers(handlers, visitor, 'claim', names)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/edx_oauth2_provider/oidc/collect.py", line 189, in _visit_handlers
    results.append(visitor(suffix, func))
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/edx_oauth2_provider/oidc/collect.py", line 128, in visitor
    claim_value = func(data)
  File "/edx/app/edxapp/edx-platform/lms/djangoapps/oauth2_handler/handlers.py", line 61, in claim_name
    profile = UserProfile.objects.get(user=user)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/edx/app/edxapp/venvs/edxapp/local/lib/python2.7/site-packages/django/db/models/query.py", line 380, in get
    self.model._meta.object_name
DoesNotExist: UserProfile matching query does not exist.

Note this error does not occur in devstack. I’ve switched from devstack to Native in order to prepare for a real deployment.

Does anybody have a clue,

Best Regards

@santifdezmunoz i’ve found a solution to my issue.
If you check LMS logs and get the same error as I mentioned if my previous reply :

DoesNotExist: UserProfile matching query does not exist.

Then I have the solution for you.

Reason

  • When ecommerce service publishes course data to LMS, it uses the ecommerce_worker user to perform operations, instead of your current user logged-in to ecommerce.
  • As the error above dictates, the user ecommerce_worker has no defined UserProfile object.
  • This error occurs only in production, while in devstack the existence of a User Profil is not required.

Solution (works only in production)

  • Go to LMS Django Admin > Authentication > Users
  • Select ecommerce_worker to edit
  • Scroll down to User Profile (inline field) and add some info (at least a name like ‘E-commerce Worker’.
  • Save your edits.

If the error persists in ecommerce, then you should check again LMS logs and find the new error which prevents the operation from working correctly.

1 Like

@ARMBouhali I would also recommend giving the ecommerceworker user staff privileges

@kribby Not sure if this is necessary for this issue, but it’s worth trying whenever there is an issue related to privileges or authorizations.

1 Like

Hi @ARMBouhali,

Thanks for your answer but unfortunatelly my error is a little bit diferent. What I’m getting in my LMS.log is
ValueError: No JSON object could be decoded
So your solution didn’t worked for me.

Anyway, thanks again for your comments.

Bests

I’ve met this error when I was trying to solve my issue above and I know it’s related to JWT authentication.
After googling the text error from both ecommerce and lms, I found this page

It suggests to edit in lms.env.json :

"JWT_PUBLIC_SIGNING_JWK_SET": null
1 Like

Thanks so much @ARMBouhali,

Seems it worked. I say seems because now I get a “You do not have permission to perform this action.” error, but I think this is just a matter of playing a little bit with the permissions.

Thanks!

i have tried set JWT_PUBLIC_SIGNING_JWK_SET": null,But The problem is still not resolved.

The log content is as follows(lms/edx.log):

paginator = self.django_paginator_class(queryset, page_size)
Mar 23 15:09:44 ip-172-31-42-57 [service_variant=lms][edx_rest_framework_extensions.auth.jwt.middleware][env:sandbox] WARNING [ip-172-31-42-57  18482] [middleware.py:62] - The view CourseRetrieveUpdateView allows Jwt Authentication but needs to include the NotJwtRestrictedApplication permission class (adding it for you)

Can anyone help me? Thank you!

@chz have you tried changing the JWT_PUBLIC_SIGNING_JWK_SET variable in both lms.yml and lms.env.json?

I have solved this problem. :smiley:

1 Like

@chz can you share with the community how did you solve the issue please?

@chz can you please share with us how did you solve the issue?

Sorry, it’s late. Recognition only applies to ironwood. This method was solved by John Swope (curricu.me). (This is not an advertisement)

The setup process is painful for me and it is easy to make mistakes. I tried three times and succeeded.
:smile:
Log onto server

Switch to edxapp user

sudo -H -u edxapp bash
source /edx/app/edxapp/edxapp_env
cd /edx/app/edxapp/edx-platform

Create a new file which you can call key_gen.py, with the following code:

from Cryptodome.PublicKey import RSA
from jwkest import jwk

# Ask for Key Identifier
key_identifier = raw_input("Key Identifier? ")

print ""
print ""

rsa_key = RSA.generate(2048)
rsa_jwk = jwk.RSAKey(kid=key_identifier, key=rsa_key)

public_keys = jwk.KEYS()
public_keys.append(rsa_jwk)
serialized_public_keys_json = public_keys.dump_jwks()

print "JWT_PUBLIC_SIGNING_JWK_SET value for ecommerce.yml and discovery.yml is"
print ""
print (serialized_public_keys_json)
print ""
print ("JWT_PUBLIC_SIGNING_JWK_SET value for lms.env.json and cms.env.json is")
JWT_PUBLIC_SIGNING_JWK_SET = serialized_public_keys_json.replace('"', '\\\\"')
print ""
print (JWT_PUBLIC_SIGNING_JWK_SET)

print ""
print ""

print ("JWT_PRIVATE_SIGNING_JWK value for lms.env.json and cms.env.json is")
# Converting to string
JWT_PRIVATE_SIGNING_JWK = str(rsa_jwk)
#print JWT_PRIVATE_SIGNING_JWK
# Replacing single quotes by double quotes
JWT_PRIVATE_SIGNING_JWK = JWT_PRIVATE_SIGNING_JWK.replace('\\'', '\\"')
#print JWT_PRIVATE_SIGNING_JWK
# Escaping double quotes
JWT_PRIVATE_SIGNING_JWK = JWT_PRIVATE_SIGNING_JWK.replace('"', '\\\\"')
#print JWT_PRIVATE_SIGNING_JWK
# removing unicode for some values
JWT_PRIVATE_SIGNING_JWK = JWT_PRIVATE_SIGNING_JWK.replace('u\\\\', '\\\\')
print ""
print (JWT_PRIVATE_SIGNING_JWK)

print ""
print ""

Run the file : python2 key_gen.py

When prompted, enter an Key ID (I think this can be anything).

ecommerce_key

YAML for JWT_PUBLIC_SIGNING_JWK_SET and JSON Arrays should be returned for JWT_PUBLIC_SIGNING_JWK_SET and JWT_PRIVATE_SIGNING_JWK. Save these.
JWT_PUBLIC_SIGNING_JWK_SET value for ecommerce.yml and discovery.yml is

{"keys": [{"kid": "ecommerce_key", "e": "AQAB", "kty": "RSA", "n": "nRAd4fvJJAn8atyavxEisT28t0yGP44AV-G-aM10GmYSP-JTZUWSMCzftaEaHewvpvzoKDQK8IZM44PXEyqr_K4lgEXdDN_4TPJ8qDv6ibgQUxLKAcxm8SfWK7rQ3IivTZeaF1zBs-efqrMJbo6piDgcRkowEyYRtDrM-2rgA4Hb4Fu8cpt0tP_sbuc1JdZVMSUCxjNfAk0YuZU9w08r0xnQf4vITMihIoX_VyBjcJve4C5S4T7jz_hwc55NYqc2pZUj9jzZlrt06vcLztcld7q5F7vvhlx09WZWjhFrwVVreYLuUORQnZ6ZF8uTmEfpCubKwstebe4CwyPipyC1eQ"}]}

JWT_PUBLIC_SIGNING_JWK_SET value for lms.env.json and cms.env.json is

{\"keys\": [{\"kid\": \"ecommerce_key\", \"e\": \"AQAB\", \"kty\": \"RSA\", \"n\": \"nRAd4fvJJAn8atyavxEisT28t0yGP44AV-G-aM10GmYSP-JTZUWSMCzftaEaHewvpvzoKDQK8IZM44PXEyqr_K4lgEXdDN_4TPJ8qDv6ibgQUxLKAcxm8SfWK7rQ3IivTZeaF1zBs-efqrMJbo6piDgcRkowEyYRtDrM-2rgA4Hb4Fu8cpt0tP_sbuc1JdZVMSUCxjNfAk0YuZU9w08r0xnQf4vITMihIoX_VyBjcJve4C5S4T7jz_hwc55NYqc2pZUj9jzZlrt06vcLztcld7q5F7vvhlx09WZWjhFrwVVreYLuUORQnZ6ZF8uTmEfpCubKwstebe4CwyPipyC1eQ\"}]}


JWT_PRIVATE_SIGNING_JWK value for lms.env.json and cms.env.json is

{\"e\": \"AQAB\", \"d\": \"DTckRzXSrdKdR4yPr2X3X6ch2uEjJp6BzuMyt0oaQSJiL2KRa82tHZqY_tpdrTOIqun6ysSI6xtnGs78E3kdXDchoVJqOsFu-LfVNKlJ97k3aRYFTfNvR06idFmAEMj7dHGTc0XIZ_p5nSOlYS-7JLgRQPoluLwU9JpB_Hb4qbLAnH6-Ptxh-Blrvj2DnGSw18nb2vdDItqduXe0D5paEF4VddfAKORC0PmldNR4xWrUFce2Jqn_P9bHC1v4Fe6GedcpI5P6OLT3ehZ01u6YXfOKcGaKqEgqAyc4TrROPM4Ta_ui6PI3sFo7DLxmylSAGWyX8KVSlkCQ4jy0mCrLBQ\", \"n\": \"nRAd4fvJJAn8atyavxEisT28t0yGP44AV-G-aM10GmYSP-JTZUWSMCzftaEaHewvpvzoKDQK8IZM44PXEyqr_K4lgEXdDN_4TPJ8qDv6ibgQUxLKAcxm8SfWK7rQ3IivTZeaF1zBs-efqrMJbo6piDgcRkowEyYRtDrM-2rgA4Hb4Fu8cpt0tP_sbuc1JdZVMSUCxjNfAk0YuZU9w08r0xnQf4vITMihIoX_VyBjcJve4C5S4T7jz_hwc55NYqc2pZUj9jzZlrt06vcLztcld7q5F7vvhlx09WZWjhFrwVVreYLuUORQnZ6ZF8uTmEfpCubKwstebe4CwyPipyC1eQ\", \"q\": \"3J4oXQRqKl-0ITFGdZBVAzsoLIW9PT492KnsG-s4q2p30YeZaiIySHre0Zw_n4cZNHJoe1DClYhrjl5ceiS4y9mdYJqbEzWFkkXEBDnNN6PjjlVPCo3AFWnTnwmh869w8nlIeUc2ylXiVKL_qIlvDzg_RrGKY-dTjPnR-AgDk3c\", \"p\": \"tkCbFOQgwXOT4gkQQFqzyb6l5oItdRemjTrwekDFebSnW7Zqo1cG5I1DMPUk335Rxd5MuUsutByHcQCNGuElmNE_ApmmTYk4Op39vNoJS8_KVfPSaBT__Im8fjO8mSZhzuYen3lCx9n94KE0Lbhz_zqg5CeqJnKWWlvS4EJi2o8\", \"kid\": \"ecommerce_key\", \"kty\": \"RSA\"}

In lms.env.json, modify JWT_PUBLIC_SIGNING_JWK_SET , JWT_PRIVATE_SIGNING_JWK , and JWT_SIGNING_ALGORITHM

The following is an excerpt with some values changed.

"JWT_AUTH": {
    "JWT_AUDIENCE": "ecommerce-key", 
    "JWT_ISSUER": "https://example.com/oauth2", 
    "JWT_ISSUERS": [
        {
            "AUDIENCE": "ecommerce-key", 
            "ISSUER": "https://example.com/oauth2", 
            "SECRET_KEY": "ecommerce-secret"
        }
    ],
"JWT_PRIVATE_SIGNING_JWK": "{\"e\": \"AQAB\", \"d\": \"DTckRzXSrdKdR4yPr2X3X6ch2uEjJp6BzuMyt0oaQSJiL2KRa82tHZqY_tpdrTOIqun6ysSI6xtnGs78E3kdXDchoVJqOsFu-LfVNKlJ97k3aRYFTfNvR06idFmAEMj7dHGTc0XIZ_p5nSOlYS-7JLgRQPoluLwU9JpB_Hb4qbLAnH6-Ptxh-Blrvj2DnGSw18nb2vdDItqduXe0D5paEF4VddfAKORC0PmldNR4xWrUFce2Jqn_P9bHC1v4Fe6GedcpI5P6OLT3ehZ01u6YXfOKcGaKqEgqAyc4TrROPM4Ta_ui6PI3sFo7DLxmylSAGWyX8KVSlkCQ4jy0mCrLBQ\", \"n\": \"nRAd4fvJJAn8atyavxEisT28t0yGP44AV-G-aM10GmYSP-JTZUWSMCzftaEaHewvpvzoKDQK8IZM44PXEyqr_K4lgEXdDN_4TPJ8qDv6ibgQUxLKAcxm8SfWK7rQ3IivTZeaF1zBs-efqrMJbo6piDgcRkowEyYRtDrM-2rgA4Hb4Fu8cpt0tP_sbuc1JdZVMSUCxjNfAk0YuZU9w08r0xnQf4vITMihIoX_VyBjcJve4C5S4T7jz_hwc55NYqc2pZUj9jzZlrt06vcLztcld7q5F7vvhlx09WZWjhFrwVVreYLuUORQnZ6ZF8uTmEfpCubKwstebe4CwyPipyC1eQ\", \"q\": \"3J4oXQRqKl-0ITFGdZBVAzsoLIW9PT492KnsG-s4q2p30YeZaiIySHre0Zw_n4cZNHJoe1DClYhrjl5ceiS4y9mdYJqbEzWFkkXEBDnNN6PjjlVPCo3AFWnTnwmh869w8nlIeUc2ylXiVKL_qIlvDzg_RrGKY-dTjPnR-AgDk3c\", \"p\": \"tkCbFOQgwXOT4gkQQFqzyb6l5oItdRemjTrwekDFebSnW7Zqo1cG5I1DMPUk335Rxd5MuUsutByHcQCNGuElmNE_ApmmTYk4Op39vNoJS8_KVfPSaBT__Im8fjO8mSZhzuYen3lCx9n94KE0Lbhz_zqg5CeqJnKWWlvS4EJi2o8\", \"kid\": \"ecommerce_key\", \"kty\": \"RSA\"}", 
"JWT_PUBLIC_SIGNING_JWK_SET": "{\"keys\": [{\"kid\": \"ecommerce_key\", \"e\": \"AQAB\", \"kty\": \"RSA\", \"n\": \"nRAd4fvJJAn8atyavxEisT28t0yGP44AV-G-aM10GmYSP-JTZUWSMCzftaEaHewvpvzoKDQK8IZM44PXEyqr_K4lgEXdDN_4TPJ8qDv6ibgQUxLKAcxm8SfWK7rQ3IivTZeaF1zBs-efqrMJbo6piDgcRkowEyYRtDrM-2rgA4Hb4Fu8cpt0tP_sbuc1JdZVMSUCxjNfAk0YuZU9w08r0xnQf4vITMihIoX_VyBjcJve4C5S4T7jz_hwc55NYqc2pZUj9jzZlrt06vcLztcld7q5F7vvhlx09WZWjhFrwVVreYLuUORQnZ6ZF8uTmEfpCubKwstebe4CwyPipyC1eQ\"}]}", 
    "JWT_SECRET_KEY": "ecommerce-secret", 
    "JWT_SIGNING_ALGORITHM": "RS512"
}, 
"JWT_EXPIRATION": 30, 
"JWT_ISSUER": "https://example.com/oauth2", 
"JWT_PRIVATE_SIGNING_KEY": "{\"e\": \"AQAB\", \"d\": \"DTckRzXSrdKdR4yPr2X3X6ch2uEjJp6BzuMyt0oaQSJiL2KRa82tHZqY_tpdrTOIqun6ysSI6xtnGs78E3kdXDchoVJqOsFu-LfVNKlJ97k3aRYFTfNvR06idFmAEMj7dHGTc0XIZ_p5nSOlYS-7JLgRQPoluLwU9JpB_Hb4qbLAnH6-Ptxh-Blrvj2DnGSw18nb2vdDItqduXe0D5paEF4VddfAKORC0PmldNR4xWrUFce2Jqn_P9bHC1v4Fe6GedcpI5P6OLT3ehZ01u6YXfOKcGaKqEgqAyc4TrROPM4Ta_ui6PI3sFo7DLxmylSAGWyX8KVSlkCQ4jy0mCrLBQ\", \"n\": \"nRAd4fvJJAn8atyavxEisT28t0yGP44AV-G-aM10GmYSP-JTZUWSMCzftaEaHewvpvzoKDQK8IZM44PXEyqr_K4lgEXdDN_4TPJ8qDv6ibgQUxLKAcxm8SfWK7rQ3IivTZeaF1zBs-efqrMJbo6piDgcRkowEyYRtDrM-2rgA4Hb4Fu8cpt0tP_sbuc1JdZVMSUCxjNfAk0YuZU9w08r0xnQf4vITMihIoX_VyBjcJve4C5S4T7jz_hwc55NYqc2pZUj9jzZlrt06vcLztcld7q5F7vvhlx09WZWjhFrwVVreYLuUORQnZ6ZF8uTmEfpCubKwstebe4CwyPipyC1eQ\", \"q\": \"3J4oXQRqKl-0ITFGdZBVAzsoLIW9PT492KnsG-s4q2p30YeZaiIySHre0Zw_n4cZNHJoe1DClYhrjl5ceiS4y9mdYJqbEzWFkkXEBDnNN6PjjlVPCo3AFWnTnwmh869w8nlIeUc2ylXiVKL_qIlvDzg_RrGKY-dTjPnR-AgDk3c\", \"p\": \"tkCbFOQgwXOT4gkQQFqzyb6l5oItdRemjTrwekDFebSnW7Zqo1cG5I1DMPUk335Rxd5MuUsutByHcQCNGuElmNE_ApmmTYk4Op39vNoJS8_KVfPSaBT__Im8fjO8mSZhzuYen3lCx9n94KE0Lbhz_zqg5CeqJnKWWlvS4EJi2o8\", \"kid\": \"ecommerce_key\", \"kty\": \"RSA\"}",

Next edit /edx/etc/ecommerce.yml and update JWT_ALGORITHM JWT_PUBLIC_SIGNING_JWK_SET

JWT_AUTH:
    JWT_ALGORITHM: RS512
    JWT_DECODE_HANDLER: ecommerce.extensions.api.handlers.jwt_decode_handler
    JWT_ISSUERS:
    -   AUDIENCE: ecommerce-key
        ISSUER: https://example.com/oauth2
        SECRET_KEY: ecommerce-secret
    -   AUDIENCE: ecommerce-key
        ISSUER: https://example.com/oauth2
        SECRET_KEY: ecommerce-secret
    JWT_LEEWAY: 1
    JWT_PUBLIC_SIGNING_JWK_SET: '{"keys": [{"kid": "ecommerce_key", "e": "AQAB", "kty": "RSA", "n": "nRAd4fvJJAn8atyavxEisT28t0yGP44AV-G-aM10GmYSP-JTZUWSMCzftaEaHewvpvzoKDQK8IZM44PXEyqr_K4lgEXdDN_4TPJ8qDv6ibgQUxLKAcxm8SfWK7rQ3IivTZeaF1zBs-efqrMJbo6piDgcRkowEyYRtDrM-2rgA4Hb4Fu8cpt0tP_sbuc1JdZVMSUCxjNfAk0YuZU9w08r0xnQf4vITMihIoX_VyBjcJve4C5S4T7jz_hwc55NYqc2pZUj9jzZlrt06vcLztcld7q5F7vvhlx09WZWjhFrwVVreYLuUORQnZ6ZF8uTmEfpCubKwstebe4CwyPipyC1eQ"}]}'
    JWT_SECRET_KEY: ecommerce-secret
    JWT_VERIFY_EXPIRATION: true


Now edit /edx/etc/discovery.yml and update JWT_ALGORITHM JWT_PUBLIC_SIGNING_JWK_SET

JWT_AUTH:
    JWT_ISSUERS:
    -   AUDIENCE: SET-ME-PLEASE
        ISSUER: https://example.com/oauth2
        SECRET_KEY: SET-ME-PLEASE
    JWT_PUBLIC_SIGNING_JWK_SET: '{"keys": [{"kid": "ecommerce_key", "e": "AQAB", "kty": "RSA", "n": "nRAd4fvJJAn8atyavxEisT28t0yGP44AV-G-aM10GmYSP-JTZUWSMCzftaEaHewvpvzoKDQK8IZM44PXEyqr_K4lgEXdDN_4TPJ8qDv6ibgQUxLKAcxm8SfWK7rQ3IivTZeaF1zBs-efqrMJbo6piDgcRkowEyYRtDrM-2rgA4Hb4Fu8cpt0tP_sbuc1JdZVMSUCxjNfAk0YuZU9w08r0xnQf4vITMihIoX_VyBjcJve4C5S4T7jz_hwc55NYqc2pZUj9jzZlrt06vcLztcld7q5F7vvhlx09WZWjhFrwVVreYLuUORQnZ6ZF8uTmEfpCubKwstebe4CwyPipyC1eQ"}]}'

Restart Everything