View Issue Details

IDProjectCategoryView StatusLast Update
0011356Talerwallet (all platforms)public2026-04-30 20:21
ReporterChristian Grothoff Assigned ToChristian Grothoff  
PriorityurgentSeverityfeatureReproducibilityN/A
Status feedbackResolutionopen 
Platformi7OSDebian GNU/LinuxOS Versionsqueeze
Product Versiongit (master) 
Target Version1.6 
Summary0011356: need paivana template support in wallet-core
DescriptionSee DD 76. Example URL:

taler+http://pay-template/localhost:9966/paivana?session_id=1776890536-kWT1KPhNWo-rmf9FeiONO144n9AICg3ue1ivCURW58M&fulfillment_url=http%3A%2F%2Flocalhost%3A8888

Steps To ReproduceCompile paivana.git, start a merchant-backend against the src/backend/test.conf, run src/backend/test.sh, then start pavivana-httpd. Visit localhost:8888/ and you should see the paywall page with the QR code.
TagsNo tags attached.

Relationships

child of 0010667 confirmedChristian Grothoff need paivana reverse proxy [4d] 
child of 0010758 confirmedChristian Grothoff turnstile should allow re-creating the order 

Activities

Christian Grothoff

2026-04-22 23:14

manager   ~0028442

Ok, I got further with the webextension, different error:

{
  "context": [],
  "cause": {
    "details": {
      "code": 7002,
      "when": {
        "t_ms": 1776892399041
      },
      "hint": "Response invalid",
      "requestUrl": "http://localhost:9966/templates/paivana",
      "requestMethod": "GET",
      "httpStatusCode": 200,
      "response": "{\n \"template_contract\": {\n \"choices\": [\n {\n \"amount\": \"KUDOS:1\"\n }\n ],\n \"summary\": \"The summary\",\n \"template_type\": \"paivana\",\n \"website_regex\": \".*\"\n }\n}",
      "validationError": "expected number at (TalerMerchantApi.WalletTemplateDetails).template_contract.minimum_age but got undefined"
    }
  }
}

Will check if 'minimum_age' is a mandatory field...

Christian Grothoff

2026-04-22 23:16

manager   ~0028443

https://docs.taler.net/core/merchant/get-templates-TEMPLATE_ID.html#get-[-instances-$INSTANCE]-templates-$TEMPLATE_ID clearly states that minimum_age is an optional field.

Christian Grothoff

2026-04-22 23:19

manager   ~0028444

Sebastian: if you can help fix this quickly, that'd be welcome ;-).

sebasjm

2026-04-24 16:25

developer   ~0028455

i will give it a try, i don't have a paivana setup but looks like a problem in taler-util

sebasjm

2026-04-24 16:50

developer   ~0028456

I see that the template interface changed a lot, it won't take me much to sync them up.
That may fix your problem

sebasjm

2026-04-24 18:13

developer   ~0028458

69b9d14ed..5c3313e86 spec updated.
all spa still doesn't support new template types that validation check is fixed

sebasjm

2026-04-24 20:10

developer   ~0028459

i have a setup now, and I can work on this next issue
image.png (31,848 bytes)   
image.png (31,848 bytes)   

sebasjm

2026-04-24 20:11

developer   ~0028460

since template_type is not yet supported is falling into the default

sebasjm

2026-04-24 20:12

developer   ~0028461

TBH You don't need a template_type in the merchant side if you already have the ID

sebasjm

2026-04-24 22:41

developer   ~0028462

this is what paivana generates

taler://pay-template/merchant.taler/paivana?session_id=1777063148-8rXGN2Yep-5Bp24VsSD2R4hES9eYZI_LwmSqsvRcluo&fulfillment_url=https%3A%2F%2Fpaivana.taler%2F

but then it fails because of paivana id

curl 'https://merchant.taler/templates/paivana' \
  --data-raw '{"template_type":"paivana","paivana_id":"1777063148-8rXGN2Yep-5Bp24VsSD2R4hES9eYZI_LwmSqsvRcluo","website":"https://paivana.taler/"}'

HTTP/1.1 400 Bad Request

{
  "code": 26,
  "hint": "A parameter in the request was malformed. This is likely a bug in the client implementation. Check if you are using the latest available version and/or file a report with the developers.",
  "detail": "paivana_id"
}

sebasjm

2026-04-24 22:42

developer   ~0028463

DEBUG Looking for by-id key RYPM9JXD of 'admin' in hashmap
INFO PAIVANA session `1777063148-8rXGN2Yep-5Bp24VsSD2R4hES9eYZI_LwmSqsvRcluo'
INFO PAIVANA after dash `8rXGN2Yep-5Bp24VsSD2R4hES9eYZI_LwmSqsvRcluo'
INFO PAIVANA website `https://paivana.taler/'
WARNING External protocol violation detected at ../src/backend/taler-merchant-httpd_post-templates-TEMPLATE_ID.c:537.
INFO Generating HTTP response with status 400 and code 26 (paivana_id)
INFO Request for `/templates/paivana' completed with HTTP status 400 (0)

Christian Grothoff

2026-04-25 22:13

manager   ~0028464

ah, my bad. I had changed it in paivana.git from SHA512 to SHA256 (to make the QR code more reasonable), but had failed to update it in the merchant backend. So this one should be fixed in a75ece57..6d58a48e.

Can you please continue testing with this change?

sebasjm

2026-04-27 14:09

developer   ~0028467

ACK, tested and something still wrong. I'm going to create a integration test

sebasjm

2026-04-27 16:02

developer   ~0028471

pull bec18897c for a int test

taler-harness run-integrationtests paivana

fails at the same spot

cat /tmp/taler-integrationtests-latest-sebasjm/paivana/merchant-httpd-testmerchant-1-stderr.log

2026-04-27T10:50:28.428514-0300 taler-merchant-httpd-110194(SXSBZBH83RFJXSR1PTJYQJ99YC) INFO Handling request (GET) for URL '/templates/paivana'
2026-04-27T10:50:28.428529-0300 taler-merchant-httpd-110194(SXSBZBH83RFJXSR1PTJYQJ99YC) DEBUG Looking for by-id key RYPM9JXD of 'admin' in hashmap
2026-04-27T10:50:28.428558-0300 taler-merchant-httpd-110194(SXSBZBH83RFJXSR1PTJYQJ99YC) DEBUG Running prepared statement `lookup_template' on 0x5cbd1444e5e0
2026-04-27T10:50:28.428566-0300 pq-110194(SXSBZBH83RFJXSR1PTJYQJ99YC) DEBUG Executing prepared SQL statement `lookup_template'
2026-04-27T10:50:28.429154-0300 pq-110194(SXSBZBH83RFJXSR1PTJYQJ99YC) DEBUG Execution of prepared SQL statement `lookup_template' finished (PGRES_TUPLES_OK)
2026-04-27T10:50:28.429413-0300 taler-merchant-httpd-110194(SXSBZBH83RFJXSR1PTJYQJ99YC) INFO Request for `/templates/paivana' completed with HTTP status 200 (0)
2026-04-27T10:50:28.429495-0300 util-scheduler-110194(SXSBZBH83RFJXSR1PTJYQJ99YC) DEBUG Adding task 0x5cbd14454c50
2026-04-27T10:50:28.431890-0300 taler-merchant-httpd-110194(5DS9CP4Z1WGV4Q01HDX9YJ2Q5R) INFO Handling request (POST) for URL '/templates/paivana'
2026-04-27T10:50:28.431921-0300 taler-merchant-httpd-110194(5DS9CP4Z1WGV4Q01HDX9YJ2Q5R) DEBUG Looking for by-id key RYPM9JXD of 'admin' in hashmap
2026-04-27T10:50:28.432004-0300 taler-merchant-httpd-110194(5DS9CP4Z1WGV4Q01HDX9YJ2Q5R) WARNING External protocol violation detected at ../src/backend/taler-merchant-httpd_post-templates-TEMPLATE_ID.c:527.
2026-04-27T10:50:28.432023-0300 taler-merchant-httpd-110194(5DS9CP4Z1WGV4Q01HDX9YJ2Q5R) INFO Generating HTTP response with status 400 and code 26 (paivana_id)
2026-04-27T10:50:28.432073-0300 taler-merchant-httpd-110194(5DS9CP4Z1WGV4Q01HDX9YJ2Q5R) INFO Request for `/templates/paivana' completed with HTTP status 400 (0)
2026-04-27T10:50:28.432096-0300 util-scheduler-110194(5DS9CP4Z1WGV4Q01HDX9YJ2Q5R) DEBUG Adding task 0x5cbd14474260

sebasjm

2026-04-27 16:09

developer   ~0028472

2b91170b3..059754090 fix log statement in wallet-core

2026-04-27T14:07:50.069Z http-impl.node.ts TRACE request 16 POST http://localhost:8083/templates/paivana: {
  "template_type": "paivana",
  "paivana_id": "1777298870-XePexh4vjS6sLQWZAPV4MAoyZ1wNeFxFCWh8rx-bVlk",
  "website": "http%3A%2F%2Flocalhost%3A8088%2Findex.html"
}
2026-04-27T14:07:50.070Z http-impl.node.ts TRACE request 16 timeout 60000 ms
2026-04-27T14:07:50.070Z http-impl.node.ts TRACE request 16 status code 400
2026-04-27T14:07:50.071Z http-impl.node.ts TRACE request 16 JSON: {
  "code": 26,
  "hint": "A parameter in the request was malformed. This is likely a bug in the client implementation. Check if you are using the latest available version and/or file a report with the developers.",
  "detail": "paivana_id"
}

sebasjm

2026-04-27 17:25

developer   ~0028475

I forgot to push a patch in paivana that adds the header

To git.taler.net:paivana
   0de0362..9089f35 master -> master

Test now fail where the logs say

Christian Grothoff

2026-04-27 22:32

manager   ~0028480

Ok, I fixed some stuff. We're now getting a 400 Bad request from the latest merchant because the wallet submits the 'website' in the POST /templates/$TEMPLATE_ID request using URI-encoding ("http%3A%2F%2Flocalhost%3A8088%2Findex.html") instead of as a simple URI --- and the URI-encoded fulfillment URL does not match the regex. This is probably because it was taken from the taler://pay-template/ URI without decoding first.
=> sebasjm: please fix in wallet-core by adding the URI decoder in the right spot.

sebasjm

2026-04-28 20:05

developer   ~0028486

Last edited: 2026-04-28 20:54

Ok fixed.

Also paivana request handler was wrongly checking .well-known that the start of the URL. Whats happening now is that merchant finds the order but reports "not found in this session ID"

As i'm seeing, the paivana id calculated in the client is ok

For example
  {
    "order_id": "2026.118-038CM8PJCXJH2",
    "nonce": "1H8XQ1EPRVG5X2FQG59NV6224M",
    "cur_time": {
      "t_s": 1777399197
    },
    "website": "http://localhost:8088/index.html"
  }



$ echo -n '1H8XQ1EPRVG5X2FQG59NV6224Mhttp://localhost:8088/index.html1777399197' | openssl dgst -sha256 -binary | base64 -w0 | sed 's/+/-/;s/\//_/;s/=//'
RQ3E3RbzJueRfOAIT9zDKjvrFrfGpwZjH570Pumv0Io

The merchant first says

2026-04-28T14:59:58.159508-0300 taler-merchant-httpd-890362(WGCPZ9FBECEB8EKJ5SZ7Q95JC8) INFO lookup_contract_terms (2026.118-038CM8PJCXJH2) returned 1
2026-04-28T14:59:58.159513-0300 taler-merchant-httpd-890362(WGCPZ9FBECEB8EKJ5SZ7Q95JC8) INFO Order 2026.118-038CM8PJCXJH2 is paid (unwired) according to database, choice 0
2026-04-28T14:59:58.159516-0300 taler-merchant-httpd-890362(WGCPZ9FBECEB8EKJ5SZ7Q95JC8) INFO Processing order 2026.118-038CM8PJCXJH2 in phase 2
2026-04-28T14:59:58.159582-0300 taler-merchant-httpd-890362(WGCPZ9FBECEB8EKJ5SZ7Q95JC8) INFO Processing order 2026.118-038CM8PJCXJH2 in phase 3
2026-04-28T14:59:58.159587-0300 taler-merchant-httpd-890362(WGCPZ9FBECEB8EKJ5SZ7Q95JC8) INFO Order 2026.118-038CM8PJCXJH2 paid for session 1777399197-RQ3E3RbzJueRfOAIT9zDKjvrFrfGpwZjH570Pumv
0Io (unwired)


And then when asked by paivana the session id is different

2026-04-28T14:59:58.168113-0300 taler-merchant-httpd-890362(NZ7653MESG6FZQ78GP77ZTG438) INFO Processing order 2026.118-038CM8PJCXJH2 in phase 1
2026-04-28T14:59:58.168120-0300 taler-merchant-httpd-890362(NZ7653MESG6FZQ78GP77ZTG438) DEBUG Running prepared statement `lookup_contract_terms3' on 0x603c621c6660
2026-04-28T14:59:58.168126-0300 pq-890362(NZ7653MESG6FZQ78GP77ZTG438) DEBUG Executing prepared SQL statement `lookup_contract_terms3'
2026-04-28T14:59:58.168265-0300 pq-890362(NZ7653MESG6FZQ78GP77ZTG438) DEBUG Execution of prepared SQL statement `lookup_contract_terms3' finished (PGRES_TUPLES_OK)
2026-04-28T14:59:58.168307-0300 taler-merchant-httpd-890362(NZ7653MESG6FZQ78GP77ZTG438) INFO lookup_contract_terms (2026.118-038CM8PJCXJH2) returned 1
2026-04-28T14:59:58.168314-0300 taler-merchant-httpd-890362(NZ7653MESG6FZQ78GP77ZTG438) INFO Order 2026.118-038CM8PJCXJH2 is paid (unwired) according to database, choice 0
2026-04-28T14:59:58.168320-0300 taler-merchant-httpd-890362(NZ7653MESG6FZQ78GP77ZTG438) INFO Processing order 2026.118-038CM8PJCXJH2 in phase 2
2026-04-28T14:59:58.168410-0300 taler-merchant-httpd-890362(NZ7653MESG6FZQ78GP77ZTG438) INFO Processing order 2026.118-038CM8PJCXJH2 in phase 3
2026-04-28T14:59:58.168417-0300 taler-merchant-httpd-890362(NZ7653MESG6FZQ78GP77ZTG438) INFO Order 2026.118-038CM8PJCXJH2 unpaid for session 1777399197-qYzCKHLZ2Aq0gS5ENwl95ONu7OKv_oIEzk0jLv-jhIE (unwired)
2026-04-28T14:59:58.168422-0300 taler-merchant-httpd-890362(NZ7653MESG6FZQ78GP77ZTG438) INFO Processing order 2026.118-038CM8PJCXJH2 in phase 4
2026-04-28T14:59:58.168428-0300 taler-merchant-httpd-890362(NZ7653MESG6FZQ78GP77ZTG438) DEBUG Running re-purchase detection for 1777399197-qYzCKHLZ2Aq0gS5ENwl95ONu7OKv_oIEzk0jLv-jhIE/http://localhost:8088/index.html


And return claimed. Not paid for that session.


Also, the example HTML uses and unspecified "pollBase" = `/.well-known/paivana/sessions/`. That will be nice in the spec so the client won't need direct access to the merchant, only the reverse proxy.

sebasjm

2026-04-28 22:26

developer   ~0028487

I checked the code in PAIVANA_HTTPD_compute_paivana_id instead of relying on the `sha256b64` implementation of the index.html and now the hash matches

2026-04-28T17:22:59.814744-0300 taler-merchant-httpd-975492(55X6M9RGGVDJ2ZKJQJTFX4YMRW) DEBUG Marking h_contract_terms 'HF10MN68' of admin as paid for session `1777407779-oPDfbgPUrWR0aWfHVai9qb7lIHkmQuI8qIYtJV16jek'
2026-04-28T17:22:59.830785-0300 taler-merchant-httpd-975492(BH20062ZS4V647TVD1ACEA88F8) INFO Order 2026.118-00WDM5HQ3NPRP paid for session 1777407779-oPDfbgPUrWR0aWfHVai9qb7lIHkmQuI8qIYtJV16jek (unwired)
2026-04-28T17:22:59.839835-0300 taler-merchant-httpd-975492(BMCKCR30MFZY9D2H66GF2SYNQ0) INFO Order 2026.118-00WDM5HQ3NPRP paid for session 1777407779-oPDfbgPUrWR0aWfHVai9qb7lIHkmQuI8qIYtJV16jek (unwired)


but paivana crashes after that

2026-04-28T17:22:58.975374-0300 paivana-httpd-975510 INFO HTTP request for `https://grothoff.org/' finished with 200 after 849 ms
2026-04-28T17:22:59.701164-0300 paivana-httpd-975510 INFO Searching templates for `http://localhost:8088/index.html'
2026-04-28T17:22:59.701280-0300 paivana-httpd-975510 INFO Payment required, sending paywall page ok
2026-04-28T17:22:59.839037-0300 paivana-httpd-975510 INFO Client POSTed payment, checking validity
2026-04-28T17:22:59.839061-0300 paivana-httpd-975510 INFO Client POSTed payment, checking validity
2026-04-28T17:22:59.839070-0300 paivana-httpd-975510 INFO Client POSTed payment, checking validity
2026-04-28T17:22:59.842392-0300 paivana-httpd-975510 ERROR Assertion failed at ../src/backend/paivana-httpd_pay.c:299. Aborting.

Christian Grothoff

2026-04-29 00:03

manager   ~0028488

Crash fixed.

sebasjm

2026-04-29 20:00

developer   ~0028489

paivana html fixed, it now produced the correct hash. Also some fixes in paivana-httpd.

Now the missing piece is wallet-core which is not setting the sessionId correctly when the template is for a repurchase. After that we can test with mobile and webex.

Christian Grothoff

2026-04-29 23:18

manager   ~0028492

Seems you wrote a test for repurchase and fixed it -- anything left that you are aware of?

sebasjm

2026-04-30 00:15

developer   ~0028493

left? no, it should work.

but...
1) I haven't tested yet with webex nor mobile phones.
2) There is no /.well-known/paivana/sessions/<sessionId> implemented in paivana-httpd (you had this in your paywall page, I replaced it for a merchant direct connection)
3) The must paywall template can be better and there is not easy way to replace it (other than override the must with a single file html+js+css)
4) It will be nice to connect from paivana-httpd to the merchant / destination using unix sock :)

i'm interested in 2 & 4 to make this run all in a raspi

Christian Grothoff

2026-04-30 00:30

manager   ~0028494

(1) We'll first need wallet-core updated on the mobile apps.
(2) Good point, I'll think about it -- not yet sure if the spec should be changed or the implementation. Can you think of a good reason why we should NOT do a direct connection to the merchant? Merchant backend has to be a public endpoint anyway, and indirect connection is just slower + more complex to implement. So is there a good reason for the .well-known/paivana/sessions/<sessionid> endpoint? Maybe CORS-stuff?
(3) The must template is supposed to be customized by each merchant for look-and-feel, and is thus supposed to be a 'clean' starting point. But yes, we probably want to support serving static files to make such custom templates easier. But easy to add. Do you see anything else that would be important here, other than loading resource files (CSS/JS) from the reverse proxy?
(4) https://curl.se/libcurl/c/CURLOPT_UNIX_SOCKET_PATH.html -- should be pretty trivial to add I think. Just a single new configuration option.

sebasjm

2026-04-30 15:41

developer   ~0028501

2) I think is too early to define and maybe the spec is better if shorter.

3) the most straight forward is to support
  a) default single-page html with everything inside (any page can be reduce to this but is inefficient for larger ones) (currently supported)
  b) server everything from a folder and subfolder (it should be under /.well-known/paivana/paywall/ in order to not to collide with proxied resources)
and switch by config, maybe if httpd can switch from (a) to (b) if SPA_DIR is present

4) yes, I actually did this for DESTINATION_BASE_URL (added a DESTINATION_UNIXPATH in the config and if present saved into PH_target_server_unixpath and used in start_curl_request, but for MERCHANT_BACKEND_URL there is no easy way to access the options. I will let you decide which is the best way to do it)

Issue History

Date Modified Username Field Change
2026-04-22 23:01 Christian Grothoff New Issue
2026-04-22 23:01 Christian Grothoff Status new => assigned
2026-04-22 23:01 Christian Grothoff Assigned To => avalos
2026-04-22 23:12 Christian Grothoff Relationship added child of 0010667
2026-04-22 23:12 Christian Grothoff Relationship added child of 0010758
2026-04-22 23:14 Christian Grothoff Note Added: 0028442
2026-04-22 23:16 Christian Grothoff Note Added: 0028443
2026-04-22 23:19 Christian Grothoff Note Added: 0028444
2026-04-24 16:25 sebasjm Note Added: 0028455
2026-04-24 16:50 sebasjm Note Added: 0028456
2026-04-24 16:50 sebasjm Assigned To avalos => sebasjm
2026-04-24 18:13 sebasjm Note Added: 0028458
2026-04-24 18:13 sebasjm Assigned To sebasjm => Christian Grothoff
2026-04-24 18:13 sebasjm Status assigned => feedback
2026-04-24 20:10 sebasjm Note Added: 0028459
2026-04-24 20:10 sebasjm File Added: image.png
2026-04-24 20:10 sebasjm Assigned To Christian Grothoff => sebasjm
2026-04-24 20:11 sebasjm Status feedback => assigned
2026-04-24 20:11 sebasjm Note Added: 0028460
2026-04-24 20:12 sebasjm Note Added: 0028461
2026-04-24 22:41 sebasjm Note Added: 0028462
2026-04-24 22:41 sebasjm Assigned To sebasjm => Christian Grothoff
2026-04-24 22:42 sebasjm Note Added: 0028463
2026-04-25 22:13 Christian Grothoff Note Added: 0028464
2026-04-25 22:13 Christian Grothoff Assigned To Christian Grothoff => sebasjm
2026-04-27 14:09 sebasjm Note Added: 0028467
2026-04-27 16:02 sebasjm Note Added: 0028471
2026-04-27 16:02 sebasjm Assigned To sebasjm => Christian Grothoff
2026-04-27 16:09 sebasjm Note Added: 0028472
2026-04-27 17:25 sebasjm Note Added: 0028475
2026-04-27 22:32 Christian Grothoff Note Added: 0028480
2026-04-27 22:32 Christian Grothoff Assigned To Christian Grothoff => sebasjm
2026-04-28 20:05 sebasjm Note Added: 0028486
2026-04-28 20:54 sebasjm Note Edited: 0028486
2026-04-28 22:26 sebasjm Note Added: 0028487
2026-04-28 23:21 Christian Grothoff Assigned To sebasjm => Christian Grothoff
2026-04-29 00:03 Christian Grothoff Note Added: 0028488
2026-04-29 00:03 Christian Grothoff Assigned To Christian Grothoff => sebasjm
2026-04-29 20:00 sebasjm Note Added: 0028489
2026-04-29 23:18 Christian Grothoff Note Added: 0028492
2026-04-30 00:15 sebasjm Note Added: 0028493
2026-04-30 00:15 sebasjm Assigned To sebasjm => Christian Grothoff
2026-04-30 00:30 Christian Grothoff Note Added: 0028494
2026-04-30 00:31 Christian Grothoff Assigned To Christian Grothoff => sebasjm
2026-04-30 00:31 Christian Grothoff Status assigned => feedback
2026-04-30 15:41 sebasjm Note Added: 0028501
2026-04-30 20:21 sebasjm Assigned To sebasjm => Christian Grothoff