@ -6,6 +6,7 @@ import com.yau.digitalrmb.institutionidentity.application.InstitutionKeyService;
import com.yau.digitalrmb.institutionidentity.application.InstitutionKeySubject ;
import com.yau.digitalrmb.institutionidentity.domain.InstitutionIdentityCryptography ;
import com.yau.digitalrmb.institutionidentity.domain.InstitutionSm2KeyPair ;
import com.yau.digitalrmb.testsupport.WalletOpeningTestData ;
import org.junit.jupiter.api.AfterEach ;
import org.junit.jupiter.api.BeforeEach ;
import org.junit.jupiter.api.Test ;
@ -45,8 +46,14 @@ class PaymentControllerTest {
@BeforeEach
void seedPrerequisites ( ) {
cleanPaymentData ( ) ;
cleanWalletState ( ) ;
insertUser ( PAYER_USER , "payment-a" , "3001" , "2001" ) ;
insertUser ( PAYEE_USER , "payment-b" , "3001" , "2001" ) ;
jdbc . update ( "INSERT INTO institution_identifier_application (id,bank_code,user_id,school_id,class_id,request_timestamp," +
"original_text,status,institution_identifier,training_round,scoring_criteria,created_at,updated_at,created_by,updated_by,deleted) " +
"VALUES (?,?,?,?,?,?,?,'ISSUED',?,2,0,CURRENT_TIMESTAMP,CURRENT_TIMESTAMP,'other','other',FALSE)" ,
991000L , "BKCHCNBJ00001" , "other-payment-user" , 9999L , 9999L ,
"20260814080000" , "OTHER_BANK" , "ORG_WRONG_SCOPE" ) ;
jdbc . update ( "INSERT INTO institution_identifier_application (id,bank_code,user_id,school_id,class_id,request_timestamp," +
"original_text,status,institution_identifier,training_round,scoring_criteria,created_at,updated_at,created_by,updated_by,deleted) " +
"VALUES (?,?,?,?,?,?,?,'ISSUED',?,1,0,CURRENT_TIMESTAMP,CURRENT_TIMESTAMP,'test','test',FALSE)" ,
@ -58,8 +65,16 @@ class PaymentControllerTest {
InstitutionKeySubject subject = new InstitutionKeySubject ( PAYER_USER , 3001L , 2001L ) ;
keyService . commercialBankKey ( subject , "test" ) ;
keyService . centralBankKey ( subject , "test" ) ;
insertWallet ( PAYER_USER , PAYER_WALLET , "CERT_PAYMENT_A" , "BKCHCNBJ00001" , "ACCOUNT_PAYMENT_A" , new BigDecimal ( "200.00" ) ) ;
insertWallet ( PAYEE_USER , PAYEE_WALLET , "CERT_PAYMENT_B" , "BKCHCNBJ00002" , "ACCOUNT_PAYMENT_B" , BigDecimal . ZERO ) ;
InstitutionSm2KeyPair payerWalletKey = cryptography . generateSm2KeyPair ( ) ;
InstitutionSm2KeyPair payeeWalletKey = cryptography . generateSm2KeyPair ( ) ;
WalletOpeningTestData . insertCompletedWallet ( jdbc , 991200L , PAYER_USER , 3001L , 2001L ,
PAYER_WALLET , payerWalletKey . getPrivateKey ( ) , payerWalletKey . getPublicKey ( ) ,
"BKCHCNBJ00001" , "6222020000000001" , BigDecimal . ZERO ) ;
WalletOpeningTestData . insertCompletedWallet ( jdbc , 991300L , PAYEE_USER , 3001L , 2001L ,
PAYEE_WALLET , payeeWalletKey . getPrivateKey ( ) , payeeWalletKey . getPublicKey ( ) ,
"BKCHCNBJ00002" , "6222020000000001" , BigDecimal . ZERO ) ;
insertWallet ( PAYER_USER , PAYER_WALLET , "CERT_991200" , "BKCHCNBJ00001" ,
"ACCOUNT_PAYMENT_A" , new BigDecimal ( "200.00" ) , payerWalletKey ) ;
insertPayerContract ( ) ;
for ( int index = 1 ; index < = 2 ; index + + ) {
jdbc . update ( "INSERT INTO commercial_bank_currency (currency_id,source_currency_id,source_batch_id,issuance_request_id," +
@ -77,12 +92,8 @@ class PaymentControllerTest {
cleanPaymentData ( ) ;
jdbc . update ( "DELETE FROM institution_sm2_key_audit WHERE user_id=?" , PAYER_USER ) ;
jdbc . update ( "DELETE FROM institution_sm2_key WHERE user_id=?" , PAYER_USER ) ;
jdbc . update ( "DELETE FROM institution_identifier_application WHERE id IN (991001,991002)" ) ;
jdbc . update ( "DELETE FROM wallet_bank_binding WHERE wallet_id IN (?,?)" , PAYER_WALLET , PAYEE_WALLET ) ;
jdbc . update ( "DELETE FROM wallet_contract WHERE wallet_id=?" , PAYER_WALLET ) ;
jdbc . update ( "DELETE FROM wallet_certificate WHERE wallet_id IN (?,?)" , PAYER_WALLET , PAYEE_WALLET ) ;
jdbc . update ( "DELETE FROM simulated_bank_account WHERE account_id IN ('ACCOUNT_PAYMENT_A','ACCOUNT_PAYMENT_B')" ) ;
jdbc . update ( "DELETE FROM digital_wallet WHERE wallet_id IN (?,?)" , PAYER_WALLET , PAYEE_WALLET ) ;
jdbc . update ( "DELETE FROM institution_identifier_application WHERE id IN (991000,991001,991002)" ) ;
cleanWalletState ( ) ;
jdbc . update ( "DELETE FROM commercial_bank_currency WHERE issuance_request_id='PAYMENT_TEST_ISSUANCE'" ) ;
jdbc . update ( "DELETE FROM sys_user WHERE user_id IN (?,?)" , PAYER_USER , PAYEE_USER ) ;
}
@ -93,7 +104,12 @@ class PaymentControllerTest {
. andExpect ( status ( ) . isOk ( ) )
. andExpect ( jsonPath ( "$.code" ) . value ( 200 ) )
. andExpect ( jsonPath ( "$.data.payer.walletId" ) . value ( PAYER_WALLET ) )
. andExpect ( jsonPath ( "$.data.payee.walletId" ) . value ( PAYEE_WALLET ) ) ;
. andExpect ( jsonPath ( "$.data.payer.organizationId" ) . value ( "ORG_PAYMENT_A" ) )
. andExpect ( jsonPath ( "$.data.payee.walletId" ) . value ( PAYEE_WALLET ) )
. andExpect ( jsonPath ( "$.data.payee.organizationId" ) . value ( "ORG_PAYMENT_B" ) ) ;
assertThat ( jdbc . queryForObject ( "SELECT COUNT(*) FROM digital_wallet WHERE wallet_id=?" , Integer . class , PAYEE_WALLET ) )
. isEqualTo ( 1 ) ;
assertThat ( jdbc . queryForObject ( "SELECT COUNT(*) FROM payment_order" , Integer . class ) ) . isZero ( ) ;
String created = mockMvc . perform ( post ( "/api/v1/payments" ) . with ( payer ( ) ) . contentType ( MediaType . APPLICATION_JSON )
. content ( "{\"payerWalletId\":\"" + PAYER_WALLET + "\",\"payeeWalletId\":\"" + PAYEE_WALLET + "\",\"amount\":200.00,\"note\":\"实验支付\"}" ) )
. andExpect ( status ( ) . isOk ( ) ) . andExpect ( jsonPath ( "$.data.status" ) . value ( "REQUEST_PREPARED" ) )
@ -140,17 +156,39 @@ class PaymentControllerTest {
. isEqualTo ( PAYEE_WALLET ) ;
}
@Test
void rejectsPaymentWhenPayerHasNoWalletOwnedCoins ( ) throws Exception {
String created = mockMvc . perform ( post ( "/api/v1/payments" ) . with ( payer ( ) ) . contentType ( MediaType . APPLICATION_JSON )
. content ( "{\"payerWalletId\":\"" + PAYER_WALLET + "\",\"payeeWalletId\":\"" + PAYEE_WALLET +
"\",\"amount\":200.00,\"note\":\"no coins\"}" ) )
. andExpect ( status ( ) . isOk ( ) )
. andReturn ( ) . getResponse ( ) . getContentAsString ( ) ;
String id = JsonPath . read ( created , "$.data.id" ) ;
mockMvc . perform ( post ( "/api/v1/payments/{id}/sign" , id ) . with ( payer ( ) ) )
. andExpect ( status ( ) . isOk ( ) ) ;
jdbc . update ( "DELETE FROM central_bank_currency_ownership WHERE owner_id=?" , PAYER_WALLET ) ;
mockMvc . perform ( post ( "/api/v1/payments/{id}/payer-bank-process" , id ) . with ( payer ( ) ) )
. andExpect ( status ( ) . isBadRequest ( ) )
. andExpect ( jsonPath ( "$.code" ) . value ( 400 ) ) ;
assertThat ( jdbc . queryForObject ( "SELECT COUNT(*) FROM payment_ownership_transfer WHERE payment_id=?" ,
Integer . class , id ) ) . isZero ( ) ;
assertThat ( jdbc . queryForObject ( "SELECT frozen_amount FROM digital_wallet WHERE wallet_id=?" ,
BigDecimal . class , PAYER_WALLET ) ) . isEqualByComparingTo ( "0.00" ) ;
}
private void insertUser ( String id , String account , String schoolId , String classId ) {
jdbc . update ( "INSERT INTO sys_user (user_id,student_id,password,user_name,class_id,class_name,school_id,school_name,role_id,is_deleted,zy_user_id) " +
"VALUES (?,?,?,?,?,'支付测试班',?,'延安大学',4,0,?)" , id , account , "unused" , account , classId , schoolId , account ) ;
}
private void insertWallet ( String userId , String walletId , String certificate , String bankCode , String accountId , BigDecimal balance ) {
InstitutionSm2KeyPair key = cryptography . generateSm2KeyPair ( ) ;
private void insertWallet ( String userId , String walletId , String certificate , String bankCode ,
String accountId , BigDecimal balance , InstitutionSm2KeyPair key ) {
jdbc . update ( "INSERT INTO digital_wallet (wallet_id,user_id,wallet_type,status,balance,frozen_amount,central_bank_confirmation_signature,opened_at,created_at,updated_at) " +
"VALUES (?,?,'TYPE_II','ACTIVE',?,0,'CB_FINAL',CURRENT_TIMESTAMP,CURRENT_TIMESTAMP,CURRENT_TIMESTAMP)" , walletId , userId , balance ) ;
"VALUES (?,?,'TYPE_II','ACTIVE',?,0,'CB_FINAL _TEST ',CURRENT_TIMESTAMP,CURRENT_TIMESTAMP,CURRENT_TIMESTAMP)", walletId , userId , balance ) ;
jdbc . update ( "INSERT INTO wallet_certificate (certificate_serial,wallet_id,public_key,encrypted_private_key,filing_status,central_bank_root_signature,status,issued_at) " +
"VALUES (?,?,?,?,'REGISTERED','CB_ROOT','VALID',CURRENT_TIMESTAMP)" , certificate , walletId , key . getPublicKey ( ) , walletCipher . encrypt ( key . getPrivateKey ( ) ) ) ;
"VALUES (?,?,?,?,'REGISTERED','CB_ROOT _TEST ','VALID',CURRENT_TIMESTAMP)", certificate , walletId , key . getPublicKey ( ) , walletCipher . encrypt ( key . getPrivateKey ( ) ) ) ;
jdbc . update ( "INSERT INTO simulated_bank_account (account_id,user_id,bank_code,bank_name,card_number,card_last4,balance,frozen_amount,status,created_at,updated_at) " +
"VALUES (?,?,?,?,'6222020000000001','0001',0,0,'ACTIVE',CURRENT_TIMESTAMP,CURRENT_TIMESTAMP)" , accountId , userId , bankCode , bankCode ) ;
jdbc . update ( "INSERT INTO wallet_bank_binding (wallet_id,bank_account_id,status,bound_at) VALUES (?,?,'BOUND',CURRENT_TIMESTAMP)" , walletId , accountId ) ;
@ -158,7 +196,17 @@ class PaymentControllerTest {
private void insertPayerContract ( ) {
jdbc . update ( "INSERT INTO wallet_contract (contract_id,wallet_id,wallet_type,single_payment_limit,daily_payment_limit,annual_payment_limit,balance_limit,valid_until,original_text,digest,status,daily_used_amount,daily_counter_date,annual_used_amount,annual_counter_year,created_at,updated_at) " +
"VALUES ('CONTRACT_PAYMENT_A',?,'TYPE_II',50000,100000,500000,500000,NULL,'CONTRACT','DIGEST','ACTIVE',0,CURRENT_DATE,0,2026,CURRENT_TIMESTAMP,CURRENT_TIMESTAMP)" , PAYER_WALLET ) ;
"VALUES ('CONTRACT_991200',?,'TYPE_II',50000,100000,500000,500000,NULL,'CONTRACT','DIGEST','ACTIVE',0,CURRENT_DATE,0,2026,CURRENT_TIMESTAMP,CURRENT_TIMESTAMP)" , PAYER_WALLET ) ;
}
private void cleanWalletState ( ) {
jdbc . update ( "DELETE FROM wallet_bank_binding WHERE wallet_id IN (?,?)" , PAYER_WALLET , PAYEE_WALLET ) ;
jdbc . update ( "DELETE FROM wallet_contract WHERE wallet_id IN (?,?)" , PAYER_WALLET , PAYEE_WALLET ) ;
jdbc . update ( "DELETE FROM wallet_certificate WHERE wallet_id IN (?,?)" , PAYER_WALLET , PAYEE_WALLET ) ;
jdbc . update ( "DELETE FROM simulated_bank_account WHERE user_id IN (?,?)" , PAYER_USER , PAYEE_USER ) ;
jdbc . update ( "DELETE FROM digital_wallet WHERE wallet_id IN (?,?)" , PAYER_WALLET , PAYEE_WALLET ) ;
WalletOpeningTestData . deleteWalletFacts ( jdbc , PAYER_USER ) ;
WalletOpeningTestData . deleteWalletFacts ( jdbc , PAYEE_USER ) ;
}
private void cleanPaymentData ( ) {